1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_svx.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include "tablecontroller.hxx"
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
34*cdf0e10cSrcweir #include <com/sun/star/container/XIndexAccess.hpp>
35*cdf0e10cSrcweir 
36*cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
37*cdf0e10cSrcweir #include <com/sun/star/table/XMergeableCellRange.hpp>
38*cdf0e10cSrcweir #include <com/sun/star/table/XMergeableCell.hpp>
39*cdf0e10cSrcweir 
40*cdf0e10cSrcweir #include <sal/config.h>
41*cdf0e10cSrcweir 
42*cdf0e10cSrcweir #include <vcl/svapp.hxx>
43*cdf0e10cSrcweir #include <svl/whiter.hxx>
44*cdf0e10cSrcweir 
45*cdf0e10cSrcweir #include <sfx2/request.hxx>
46*cdf0e10cSrcweir 
47*cdf0e10cSrcweir #include <editeng/scripttypeitem.hxx>
48*cdf0e10cSrcweir #include <svx/svdotable.hxx>
49*cdf0e10cSrcweir #include <svx/sdr/overlay/overlayobjectcell.hxx>
50*cdf0e10cSrcweir #include <svx/sdr/overlay/overlaymanager.hxx>
51*cdf0e10cSrcweir #include <svx/svxids.hrc>
52*cdf0e10cSrcweir #include <editeng/outlobj.hxx>
53*cdf0e10cSrcweir #include <svx/svdoutl.hxx>
54*cdf0e10cSrcweir #include <svx/svdpagv.hxx>
55*cdf0e10cSrcweir #include <svx/svdetc.hxx>
56*cdf0e10cSrcweir #include <editeng/editobj.hxx>
57*cdf0e10cSrcweir #include "editeng/editstat.hxx"
58*cdf0e10cSrcweir #include "editeng/unolingu.hxx"
59*cdf0e10cSrcweir #include "svx/sdrpagewindow.hxx"
60*cdf0e10cSrcweir #include <svx/selectioncontroller.hxx>
61*cdf0e10cSrcweir #include <svx/svdmodel.hxx>
62*cdf0e10cSrcweir #include "svx/sdrpaintwindow.hxx"
63*cdf0e10cSrcweir #include <svx/svxdlg.hxx>
64*cdf0e10cSrcweir #include <editeng/boxitem.hxx>
65*cdf0e10cSrcweir #include "cell.hxx"
66*cdf0e10cSrcweir #include <editeng/borderline.hxx>
67*cdf0e10cSrcweir #include <editeng/colritem.hxx>
68*cdf0e10cSrcweir #include "editeng/bolnitem.hxx"
69*cdf0e10cSrcweir #include "svx/svdstr.hrc"
70*cdf0e10cSrcweir #include "svx/svdglob.hxx"
71*cdf0e10cSrcweir #include "svx/svdpage.hxx"
72*cdf0e10cSrcweir #include "tableundo.hxx"
73*cdf0e10cSrcweir #include "tablelayouter.hxx"
74*cdf0e10cSrcweir 
75*cdf0e10cSrcweir using ::rtl::OUString;
76*cdf0e10cSrcweir using namespace ::sdr::table;
77*cdf0e10cSrcweir using namespace ::com::sun::star;
78*cdf0e10cSrcweir using namespace ::com::sun::star::uno;
79*cdf0e10cSrcweir using namespace ::com::sun::star::table;
80*cdf0e10cSrcweir using namespace ::com::sun::star::beans;
81*cdf0e10cSrcweir using namespace ::com::sun::star::container;
82*cdf0e10cSrcweir using namespace ::com::sun::star::text;
83*cdf0e10cSrcweir using namespace ::com::sun::star::style;
84*cdf0e10cSrcweir 
85*cdf0e10cSrcweir namespace sdr { namespace table {
86*cdf0e10cSrcweir 
87*cdf0e10cSrcweir // --------------------------------------------------------------------
88*cdf0e10cSrcweir // class SvxTableControllerModifyListener
89*cdf0e10cSrcweir // --------------------------------------------------------------------
90*cdf0e10cSrcweir 
91*cdf0e10cSrcweir class SvxTableControllerModifyListener : public ::cppu::WeakImplHelper1< ::com::sun::star::util::XModifyListener >
92*cdf0e10cSrcweir {
93*cdf0e10cSrcweir public:
94*cdf0e10cSrcweir 	SvxTableControllerModifyListener( SvxTableController* pController )
95*cdf0e10cSrcweir 		: mpController( pController ) {}
96*cdf0e10cSrcweir 
97*cdf0e10cSrcweir 	// XModifyListener
98*cdf0e10cSrcweir     virtual void SAL_CALL modified( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::RuntimeException);
99*cdf0e10cSrcweir 
100*cdf0e10cSrcweir     // XEventListener
101*cdf0e10cSrcweir     virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException);
102*cdf0e10cSrcweir 
103*cdf0e10cSrcweir 	SvxTableController* mpController;
104*cdf0e10cSrcweir };
105*cdf0e10cSrcweir 
106*cdf0e10cSrcweir // --------------------------------------------------------------------
107*cdf0e10cSrcweir // XModifyListener
108*cdf0e10cSrcweir // --------------------------------------------------------------------
109*cdf0e10cSrcweir 
110*cdf0e10cSrcweir void SAL_CALL SvxTableControllerModifyListener::modified( const ::com::sun::star::lang::EventObject&  ) throw (::com::sun::star::uno::RuntimeException)
111*cdf0e10cSrcweir {
112*cdf0e10cSrcweir 	if( mpController )
113*cdf0e10cSrcweir 		mpController->onTableModified();
114*cdf0e10cSrcweir }
115*cdf0e10cSrcweir 
116*cdf0e10cSrcweir // --------------------------------------------------------------------
117*cdf0e10cSrcweir // XEventListener
118*cdf0e10cSrcweir // --------------------------------------------------------------------
119*cdf0e10cSrcweir 
120*cdf0e10cSrcweir void SAL_CALL SvxTableControllerModifyListener::disposing( const ::com::sun::star::lang::EventObject&  ) throw (::com::sun::star::uno::RuntimeException)
121*cdf0e10cSrcweir {
122*cdf0e10cSrcweir 	mpController = 0;
123*cdf0e10cSrcweir }
124*cdf0e10cSrcweir 
125*cdf0e10cSrcweir // --------------------------------------------------------------------
126*cdf0e10cSrcweir // class SvxTableController
127*cdf0e10cSrcweir // --------------------------------------------------------------------
128*cdf0e10cSrcweir 
129*cdf0e10cSrcweir rtl::Reference< sdr::SelectionController > CreateTableController( SdrObjEditView* pView, const SdrObject* pObj, const rtl::Reference< sdr::SelectionController >& xRefController )
130*cdf0e10cSrcweir {
131*cdf0e10cSrcweir 	return SvxTableController::create( pView, pObj, xRefController );
132*cdf0e10cSrcweir }
133*cdf0e10cSrcweir 
134*cdf0e10cSrcweir // --------------------------------------------------------------------
135*cdf0e10cSrcweir 
136*cdf0e10cSrcweir rtl::Reference< sdr::SelectionController > SvxTableController::create( SdrObjEditView* pView, const SdrObject* pObj, const rtl::Reference< sdr::SelectionController >& xRefController )
137*cdf0e10cSrcweir {
138*cdf0e10cSrcweir 	if( xRefController.is() )
139*cdf0e10cSrcweir 	{
140*cdf0e10cSrcweir 		SvxTableController* pController = dynamic_cast< SvxTableController* >( xRefController.get() );
141*cdf0e10cSrcweir 		if( pController && (pController->mxTableObj.get() == pObj) && (pController->mpView == pView)  )
142*cdf0e10cSrcweir 			return xRefController;
143*cdf0e10cSrcweir 	}
144*cdf0e10cSrcweir 	return new SvxTableController( pView, pObj );
145*cdf0e10cSrcweir }
146*cdf0e10cSrcweir 
147*cdf0e10cSrcweir // --------------------------------------------------------------------
148*cdf0e10cSrcweir 
149*cdf0e10cSrcweir SvxTableController::SvxTableController( SdrObjEditView* pView, const SdrObject* pObj )
150*cdf0e10cSrcweir : mbCellSelectionMode(false)
151*cdf0e10cSrcweir , mbLeftButtonDown(false)
152*cdf0e10cSrcweir , mpSelectionOverlay(0)
153*cdf0e10cSrcweir , mpView( dynamic_cast< SdrView* >( pView ) )
154*cdf0e10cSrcweir , mxTableObj( dynamic_cast< SdrTableObj* >( const_cast< SdrObject* >( pObj ) ) )
155*cdf0e10cSrcweir , mpModel( 0 )
156*cdf0e10cSrcweir , mnUpdateEvent( 0 )
157*cdf0e10cSrcweir {
158*cdf0e10cSrcweir 	if( pObj )
159*cdf0e10cSrcweir 		mpModel = pObj->GetModel();
160*cdf0e10cSrcweir 
161*cdf0e10cSrcweir 	if( mxTableObj.is() )
162*cdf0e10cSrcweir 	{
163*cdf0e10cSrcweir 		static_cast< const SdrTableObj* >( pObj )->getActiveCellPos( maCursorFirstPos );
164*cdf0e10cSrcweir 		maCursorLastPos = maCursorFirstPos;
165*cdf0e10cSrcweir 
166*cdf0e10cSrcweir 		Reference< XTable > xTable( static_cast< const SdrTableObj* >( pObj )->getTable() );
167*cdf0e10cSrcweir 		if( xTable.is() )
168*cdf0e10cSrcweir 		{
169*cdf0e10cSrcweir 			mxModifyListener = new SvxTableControllerModifyListener( this );
170*cdf0e10cSrcweir 			xTable->addModifyListener( mxModifyListener );
171*cdf0e10cSrcweir 
172*cdf0e10cSrcweir 			mxTable.set( dynamic_cast< TableModel* >( xTable.get() ) );
173*cdf0e10cSrcweir 		}
174*cdf0e10cSrcweir 	}
175*cdf0e10cSrcweir }
176*cdf0e10cSrcweir 
177*cdf0e10cSrcweir // --------------------------------------------------------------------
178*cdf0e10cSrcweir 
179*cdf0e10cSrcweir SvxTableController::~SvxTableController()
180*cdf0e10cSrcweir {
181*cdf0e10cSrcweir 	if( mnUpdateEvent )
182*cdf0e10cSrcweir 	{
183*cdf0e10cSrcweir 		Application::RemoveUserEvent( mnUpdateEvent );
184*cdf0e10cSrcweir 	}
185*cdf0e10cSrcweir 
186*cdf0e10cSrcweir 	if( mxModifyListener.is() && mxTableObj.get() )
187*cdf0e10cSrcweir 	{
188*cdf0e10cSrcweir 		Reference< XTable > xTable( static_cast< SdrTableObj* >( mxTableObj.get() )->getTable() );
189*cdf0e10cSrcweir 		if( xTable.is() )
190*cdf0e10cSrcweir 		{
191*cdf0e10cSrcweir 			xTable->removeModifyListener( mxModifyListener );
192*cdf0e10cSrcweir 			mxModifyListener.clear();
193*cdf0e10cSrcweir 		}
194*cdf0e10cSrcweir 	}
195*cdf0e10cSrcweir }
196*cdf0e10cSrcweir 
197*cdf0e10cSrcweir // --------------------------------------------------------------------
198*cdf0e10cSrcweir 
199*cdf0e10cSrcweir const sal_uInt16 ACTION_NONE = 0;
200*cdf0e10cSrcweir const sal_uInt16 ACTION_GOTO_FIRST_CELL = 1;
201*cdf0e10cSrcweir const sal_uInt16 ACTION_GOTO_FIRST_COLUMN = 2;
202*cdf0e10cSrcweir const sal_uInt16 ACTION_GOTO_FIRST_ROW = 3;
203*cdf0e10cSrcweir const sal_uInt16 ACTION_GOTO_LEFT_CELL = 4;
204*cdf0e10cSrcweir const sal_uInt16 ACTION_GOTO_UP_CELL = 5;
205*cdf0e10cSrcweir const sal_uInt16 ACTION_GOTO_RIGHT_CELL = 6;
206*cdf0e10cSrcweir const sal_uInt16 ACTION_GOTO_DOWN_CELL = 7;
207*cdf0e10cSrcweir const sal_uInt16 ACTION_GOTO_LAST_CELL = 8;
208*cdf0e10cSrcweir const sal_uInt16 ACTION_GOTO_LAST_COLUMN = 9;
209*cdf0e10cSrcweir const sal_uInt16 ACTION_GOTO_LAST_ROW = 10;
210*cdf0e10cSrcweir const sal_uInt16 ACTION_EDIT_CELL = 11;
211*cdf0e10cSrcweir const sal_uInt16 ACTION_STOP_TEXT_EDIT = 12;
212*cdf0e10cSrcweir const sal_uInt16 ACTION_REMOVE_SELECTION = 13;
213*cdf0e10cSrcweir const sal_uInt16 ACTION_START_SELECTION = 14;
214*cdf0e10cSrcweir const sal_uInt16 ACTION_HANDLED_BY_VIEW = 15;
215*cdf0e10cSrcweir const sal_uInt16 ACTION_TAB = 18;
216*cdf0e10cSrcweir 
217*cdf0e10cSrcweir bool SvxTableController::onKeyInput(const KeyEvent& rKEvt, Window* pWindow )
218*cdf0e10cSrcweir {
219*cdf0e10cSrcweir 	if( !checkTableObject() )
220*cdf0e10cSrcweir 		return false;
221*cdf0e10cSrcweir 
222*cdf0e10cSrcweir 	// check if we are read only
223*cdf0e10cSrcweir 	if( mpModel && mpModel->IsReadOnly())
224*cdf0e10cSrcweir 	{
225*cdf0e10cSrcweir 		switch( rKEvt.GetKeyCode().GetCode() )
226*cdf0e10cSrcweir 		{
227*cdf0e10cSrcweir 		case awt::Key::DOWN:
228*cdf0e10cSrcweir 		case awt::Key::UP:
229*cdf0e10cSrcweir 		case awt::Key::LEFT:
230*cdf0e10cSrcweir 		case awt::Key::RIGHT:
231*cdf0e10cSrcweir 		case awt::Key::TAB:
232*cdf0e10cSrcweir 		case awt::Key::HOME:
233*cdf0e10cSrcweir 		case awt::Key::END:
234*cdf0e10cSrcweir 		case awt::Key::NUM2:
235*cdf0e10cSrcweir 		case awt::Key::NUM4:
236*cdf0e10cSrcweir 		case awt::Key::NUM6:
237*cdf0e10cSrcweir 		case awt::Key::NUM8:
238*cdf0e10cSrcweir 		case awt::Key::ESCAPE:
239*cdf0e10cSrcweir 		case awt::Key::F2:
240*cdf0e10cSrcweir 			break;
241*cdf0e10cSrcweir 		default:
242*cdf0e10cSrcweir 			// tell the view we eat the event, no further processing needed
243*cdf0e10cSrcweir 			return true;
244*cdf0e10cSrcweir 		}
245*cdf0e10cSrcweir 	}
246*cdf0e10cSrcweir 
247*cdf0e10cSrcweir 	sal_uInt16 nAction = getKeyboardAction( rKEvt, pWindow );
248*cdf0e10cSrcweir 
249*cdf0e10cSrcweir 	return executeAction( nAction, ( rKEvt.GetKeyCode().IsShift() ) ? sal_True : sal_False, pWindow );
250*cdf0e10cSrcweir }
251*cdf0e10cSrcweir 
252*cdf0e10cSrcweir // --------------------------------------------------------------------
253*cdf0e10cSrcweir // ::com::sun::star::awt::XMouseClickHandler:
254*cdf0e10cSrcweir // --------------------------------------------------------------------
255*cdf0e10cSrcweir 
256*cdf0e10cSrcweir bool SvxTableController::onMouseButtonDown(const MouseEvent& rMEvt, Window* pWindow )
257*cdf0e10cSrcweir {
258*cdf0e10cSrcweir 	if( !pWindow || !checkTableObject() )
259*cdf0e10cSrcweir 		return false;
260*cdf0e10cSrcweir 
261*cdf0e10cSrcweir 	SdrViewEvent aVEvt;
262*cdf0e10cSrcweir 	if( !rMEvt.IsRight() && mpView->PickAnything(rMEvt,SDRMOUSEBUTTONDOWN, aVEvt) == SDRHIT_HANDLE )
263*cdf0e10cSrcweir 		return false;
264*cdf0e10cSrcweir 
265*cdf0e10cSrcweir 	TableHitKind eHit = static_cast< SdrTableObj* >(mxTableObj.get())->CheckTableHit( pWindow->PixelToLogic(rMEvt.GetPosPixel()), maMouseDownPos.mnCol, maMouseDownPos.mnRow, 0 );
266*cdf0e10cSrcweir 
267*cdf0e10cSrcweir 	mbLeftButtonDown = (rMEvt.GetClicks() == 1) && rMEvt.IsLeft();
268*cdf0e10cSrcweir 
269*cdf0e10cSrcweir 	if( eHit == SDRTABLEHIT_CELL )
270*cdf0e10cSrcweir 	{
271*cdf0e10cSrcweir 		StartSelection( maMouseDownPos );
272*cdf0e10cSrcweir 		return true;
273*cdf0e10cSrcweir 	}
274*cdf0e10cSrcweir 
275*cdf0e10cSrcweir 	if( rMEvt.IsRight() && eHit != SDRTABLEHIT_NONE )
276*cdf0e10cSrcweir 		return true; // right click will become context menu
277*cdf0e10cSrcweir 
278*cdf0e10cSrcweir 	// for cell selektion with the mouse remember our first hit
279*cdf0e10cSrcweir 	if( mbLeftButtonDown )
280*cdf0e10cSrcweir 	{
281*cdf0e10cSrcweir 		RemoveSelection();
282*cdf0e10cSrcweir 
283*cdf0e10cSrcweir 		Point aPnt(rMEvt.GetPosPixel());
284*cdf0e10cSrcweir 		if (pWindow!=NULL)
285*cdf0e10cSrcweir 			aPnt=pWindow->PixelToLogic(aPnt);
286*cdf0e10cSrcweir 
287*cdf0e10cSrcweir 		SdrHdl* pHdl = mpView->PickHandle(aPnt);
288*cdf0e10cSrcweir 
289*cdf0e10cSrcweir 		if( pHdl )
290*cdf0e10cSrcweir 		{
291*cdf0e10cSrcweir 			mbLeftButtonDown = false;
292*cdf0e10cSrcweir 		}
293*cdf0e10cSrcweir 		else
294*cdf0e10cSrcweir 		{
295*cdf0e10cSrcweir 			::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
296*cdf0e10cSrcweir 
297*cdf0e10cSrcweir 			if( !pWindow || !pTableObj || eHit  == SDRTABLEHIT_NONE)
298*cdf0e10cSrcweir 			{
299*cdf0e10cSrcweir 				mbLeftButtonDown = false;
300*cdf0e10cSrcweir 			}
301*cdf0e10cSrcweir 		}
302*cdf0e10cSrcweir 	}
303*cdf0e10cSrcweir 
304*cdf0e10cSrcweir 	return false;
305*cdf0e10cSrcweir }
306*cdf0e10cSrcweir 
307*cdf0e10cSrcweir // --------------------------------------------------------------------
308*cdf0e10cSrcweir 
309*cdf0e10cSrcweir bool SvxTableController::onMouseButtonUp(const MouseEvent& rMEvt, Window* /*pWin*/)
310*cdf0e10cSrcweir {
311*cdf0e10cSrcweir 	if( !checkTableObject() )
312*cdf0e10cSrcweir 		return false;
313*cdf0e10cSrcweir 
314*cdf0e10cSrcweir 	mbLeftButtonDown = false;
315*cdf0e10cSrcweir 
316*cdf0e10cSrcweir 	if( rMEvt.GetClicks() == 2 )
317*cdf0e10cSrcweir 		return true;
318*cdf0e10cSrcweir 
319*cdf0e10cSrcweir 	return false;
320*cdf0e10cSrcweir }
321*cdf0e10cSrcweir 
322*cdf0e10cSrcweir // --------------------------------------------------------------------
323*cdf0e10cSrcweir 
324*cdf0e10cSrcweir bool SvxTableController::onMouseMove(const MouseEvent& rMEvt, Window* pWindow )
325*cdf0e10cSrcweir {
326*cdf0e10cSrcweir 	if( !checkTableObject() )
327*cdf0e10cSrcweir 		return false;
328*cdf0e10cSrcweir 
329*cdf0e10cSrcweir 	if( rMEvt.IsLeft() )
330*cdf0e10cSrcweir 	{
331*cdf0e10cSrcweir 		int i = 0;
332*cdf0e10cSrcweir 		i++;
333*cdf0e10cSrcweir 	}
334*cdf0e10cSrcweir 
335*cdf0e10cSrcweir 	SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >( mxTableObj.get() );
336*cdf0e10cSrcweir 	CellPos aPos;
337*cdf0e10cSrcweir 	if( mbLeftButtonDown && pTableObj && pTableObj->CheckTableHit( pWindow->PixelToLogic(rMEvt.GetPosPixel()), aPos.mnCol, aPos.mnRow, 0 ) != SDRTABLEHIT_NONE )
338*cdf0e10cSrcweir 	{
339*cdf0e10cSrcweir 		if(aPos != maMouseDownPos)
340*cdf0e10cSrcweir 		{
341*cdf0e10cSrcweir 			if( mbCellSelectionMode )
342*cdf0e10cSrcweir 			{
343*cdf0e10cSrcweir 				setSelectedCells( maMouseDownPos, aPos );
344*cdf0e10cSrcweir 				return true;
345*cdf0e10cSrcweir 			}
346*cdf0e10cSrcweir 			else
347*cdf0e10cSrcweir 			{
348*cdf0e10cSrcweir 				StartSelection( maMouseDownPos );
349*cdf0e10cSrcweir 			}
350*cdf0e10cSrcweir 		}
351*cdf0e10cSrcweir 		else if( mbCellSelectionMode )
352*cdf0e10cSrcweir 		{
353*cdf0e10cSrcweir 			UpdateSelection( aPos );
354*cdf0e10cSrcweir 			return true;
355*cdf0e10cSrcweir 		}
356*cdf0e10cSrcweir 	}
357*cdf0e10cSrcweir     return false;
358*cdf0e10cSrcweir }
359*cdf0e10cSrcweir 
360*cdf0e10cSrcweir // --------------------------------------------------------------------
361*cdf0e10cSrcweir 
362*cdf0e10cSrcweir void SvxTableController::onSelectionHasChanged()
363*cdf0e10cSrcweir {
364*cdf0e10cSrcweir 	bool bSelected = false;
365*cdf0e10cSrcweir 
366*cdf0e10cSrcweir 	SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >( mxTableObj.get() );
367*cdf0e10cSrcweir 	if( pTableObj && pTableObj->IsTextEditActive() )
368*cdf0e10cSrcweir 	{
369*cdf0e10cSrcweir 		pTableObj->getActiveCellPos( maCursorFirstPos );
370*cdf0e10cSrcweir 		maCursorLastPos = maCursorFirstPos;
371*cdf0e10cSrcweir 		mbCellSelectionMode = false;
372*cdf0e10cSrcweir 	}
373*cdf0e10cSrcweir 	else
374*cdf0e10cSrcweir 	{
375*cdf0e10cSrcweir 		const SdrMarkList& rMarkList= mpView->GetMarkedObjectList();
376*cdf0e10cSrcweir 		if( rMarkList.GetMarkCount() == 1 )
377*cdf0e10cSrcweir 			bSelected = mxTableObj.get() == rMarkList.GetMark(0)->GetMarkedSdrObj();
378*cdf0e10cSrcweir 	}
379*cdf0e10cSrcweir 
380*cdf0e10cSrcweir 	if( bSelected )
381*cdf0e10cSrcweir 	{
382*cdf0e10cSrcweir 		updateSelectionOverlay();
383*cdf0e10cSrcweir 	}
384*cdf0e10cSrcweir 	else
385*cdf0e10cSrcweir 	{
386*cdf0e10cSrcweir 		destroySelectionOverlay();
387*cdf0e10cSrcweir 	}
388*cdf0e10cSrcweir }
389*cdf0e10cSrcweir 
390*cdf0e10cSrcweir // --------------------------------------------------------------------
391*cdf0e10cSrcweir 
392*cdf0e10cSrcweir void SvxTableController::GetState( SfxItemSet& rSet )
393*cdf0e10cSrcweir {
394*cdf0e10cSrcweir 	if( !mxTable.is() || !mxTableObj.is() || !mxTableObj->GetModel() )
395*cdf0e10cSrcweir 		return;
396*cdf0e10cSrcweir 
397*cdf0e10cSrcweir 	SfxItemSet* pSet = 0;
398*cdf0e10cSrcweir 
399*cdf0e10cSrcweir 	bool bVertDone = false;
400*cdf0e10cSrcweir 
401*cdf0e10cSrcweir     // Iterate over all requested items in the set.
402*cdf0e10cSrcweir 	SfxWhichIter aIter( rSet );
403*cdf0e10cSrcweir 	sal_uInt16 nWhich = aIter.FirstWhich();
404*cdf0e10cSrcweir 	while (nWhich)
405*cdf0e10cSrcweir 	{
406*cdf0e10cSrcweir 		switch (nWhich)
407*cdf0e10cSrcweir 		{
408*cdf0e10cSrcweir 			case SID_TABLE_VERT_BOTTOM:
409*cdf0e10cSrcweir 			case SID_TABLE_VERT_CENTER:
410*cdf0e10cSrcweir 			case SID_TABLE_VERT_NONE:
411*cdf0e10cSrcweir 				{
412*cdf0e10cSrcweir 					if( !mxTable.is() || !mxTableObj->GetModel() )
413*cdf0e10cSrcweir 					{
414*cdf0e10cSrcweir 						rSet.DisableItem(nWhich);
415*cdf0e10cSrcweir 					}
416*cdf0e10cSrcweir 					else if(!bVertDone)
417*cdf0e10cSrcweir 					{
418*cdf0e10cSrcweir 						if( !pSet )
419*cdf0e10cSrcweir 						{
420*cdf0e10cSrcweir 							pSet = new SfxItemSet( mxTableObj->GetModel()->GetItemPool() );
421*cdf0e10cSrcweir 							MergeAttrFromSelectedCells(*pSet, sal_False);
422*cdf0e10cSrcweir 						}
423*cdf0e10cSrcweir 
424*cdf0e10cSrcweir 						SdrTextVertAdjust eAdj = SDRTEXTVERTADJUST_BLOCK;
425*cdf0e10cSrcweir 
426*cdf0e10cSrcweir 						if( pSet->GetItemState( SDRATTR_TEXT_VERTADJUST ) != SFX_ITEM_DONTCARE )
427*cdf0e10cSrcweir 							eAdj = ((SdrTextVertAdjustItem&)(pSet->Get(SDRATTR_TEXT_VERTADJUST))).GetValue();
428*cdf0e10cSrcweir 
429*cdf0e10cSrcweir 						rSet.Put(SfxBoolItem(SID_TABLE_VERT_BOTTOM, eAdj == SDRTEXTVERTADJUST_BOTTOM));
430*cdf0e10cSrcweir 						rSet.Put(SfxBoolItem(SID_TABLE_VERT_CENTER, eAdj == SDRTEXTVERTADJUST_CENTER));
431*cdf0e10cSrcweir 						rSet.Put(SfxBoolItem(SID_TABLE_VERT_NONE, eAdj == SDRTEXTVERTADJUST_TOP));
432*cdf0e10cSrcweir 						bVertDone = true;
433*cdf0e10cSrcweir 					}
434*cdf0e10cSrcweir 					break;
435*cdf0e10cSrcweir 				}
436*cdf0e10cSrcweir 			case SID_TABLE_DELETE_ROW:
437*cdf0e10cSrcweir 				if( !mxTable.is() || !hasSelectedCells() || (mxTable->getRowCount() <= 1) )
438*cdf0e10cSrcweir 					rSet.DisableItem(SID_TABLE_DELETE_ROW);
439*cdf0e10cSrcweir 				break;
440*cdf0e10cSrcweir 			case SID_TABLE_DELETE_COL:
441*cdf0e10cSrcweir 				if( !mxTable.is() || !hasSelectedCells() || (mxTable->getColumnCount() <= 1) )
442*cdf0e10cSrcweir 					rSet.DisableItem(SID_TABLE_DELETE_COL);
443*cdf0e10cSrcweir 				break;
444*cdf0e10cSrcweir 			case SID_TABLE_MERGE_CELLS:
445*cdf0e10cSrcweir 				if( !mxTable.is() || !hasSelectedCells() )
446*cdf0e10cSrcweir 					rSet.DisableItem(SID_TABLE_MERGE_CELLS);
447*cdf0e10cSrcweir 				break;
448*cdf0e10cSrcweir 			case SID_TABLE_SPLIT_CELLS:
449*cdf0e10cSrcweir 				if( !hasSelectedCells() || !mxTable.is() )
450*cdf0e10cSrcweir 					rSet.DisableItem(SID_TABLE_SPLIT_CELLS);
451*cdf0e10cSrcweir 				break;
452*cdf0e10cSrcweir 
453*cdf0e10cSrcweir 			case SID_OPTIMIZE_TABLE:
454*cdf0e10cSrcweir 			case SID_TABLE_DISTRIBUTE_COLUMNS:
455*cdf0e10cSrcweir 			case SID_TABLE_DISTRIBUTE_ROWS:
456*cdf0e10cSrcweir 			{
457*cdf0e10cSrcweir 				bool bDistributeColumns = false;
458*cdf0e10cSrcweir 				bool bDistributeRows = false;
459*cdf0e10cSrcweir 				if( mxTable.is() )
460*cdf0e10cSrcweir 				{
461*cdf0e10cSrcweir 					CellPos aStart, aEnd;
462*cdf0e10cSrcweir 					getSelectedCells( aStart, aEnd );
463*cdf0e10cSrcweir 
464*cdf0e10cSrcweir 					bDistributeColumns = aStart.mnCol != aEnd.mnCol;
465*cdf0e10cSrcweir 					bDistributeRows = aStart.mnRow != aEnd.mnRow;
466*cdf0e10cSrcweir 				}
467*cdf0e10cSrcweir 				if( !bDistributeColumns && !bDistributeRows )
468*cdf0e10cSrcweir 					rSet.DisableItem(SID_OPTIMIZE_TABLE);
469*cdf0e10cSrcweir 				if( !bDistributeColumns )
470*cdf0e10cSrcweir 					rSet.DisableItem(SID_TABLE_DISTRIBUTE_COLUMNS);
471*cdf0e10cSrcweir 				if( !bDistributeRows )
472*cdf0e10cSrcweir 					rSet.DisableItem(SID_TABLE_DISTRIBUTE_ROWS);
473*cdf0e10cSrcweir 				break;
474*cdf0e10cSrcweir 			}
475*cdf0e10cSrcweir 
476*cdf0e10cSrcweir 			case SID_AUTOFORMAT:
477*cdf0e10cSrcweir 			case SID_TABLE_SORT_DIALOG:
478*cdf0e10cSrcweir 			case SID_TABLE_AUTOSUM:
479*cdf0e10cSrcweir //				if( !mxTable.is() )
480*cdf0e10cSrcweir //					rSet.DisableItem( nWhich );
481*cdf0e10cSrcweir 				break;
482*cdf0e10cSrcweir 			default:
483*cdf0e10cSrcweir 				break;
484*cdf0e10cSrcweir         }
485*cdf0e10cSrcweir 		nWhich = aIter.NextWhich();
486*cdf0e10cSrcweir 	}
487*cdf0e10cSrcweir 	if( pSet )
488*cdf0e10cSrcweir 		delete pSet;
489*cdf0e10cSrcweir }
490*cdf0e10cSrcweir 
491*cdf0e10cSrcweir // --------------------------------------------------------------------
492*cdf0e10cSrcweir 
493*cdf0e10cSrcweir void SvxTableController::onInsert( sal_uInt16 nSId, const SfxItemSet* pArgs )
494*cdf0e10cSrcweir {
495*cdf0e10cSrcweir 	::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
496*cdf0e10cSrcweir 	if( !pTableObj )
497*cdf0e10cSrcweir 		return;
498*cdf0e10cSrcweir 
499*cdf0e10cSrcweir 	if( mxTable.is() ) try
500*cdf0e10cSrcweir 	{
501*cdf0e10cSrcweir 		//
502*cdf0e10cSrcweir 		bool bInsertAfter = true;
503*cdf0e10cSrcweir 		sal_uInt16 nCount = 0;
504*cdf0e10cSrcweir     	if( pArgs )
505*cdf0e10cSrcweir     	{
506*cdf0e10cSrcweir     	    const SfxPoolItem* pItem = 0;
507*cdf0e10cSrcweir     	    pArgs->GetItemState(nSId, sal_False, &pItem);
508*cdf0e10cSrcweir 			if (pItem)
509*cdf0e10cSrcweir 			{
510*cdf0e10cSrcweir 				nCount = ((const SfxInt16Item* )pItem)->GetValue();
511*cdf0e10cSrcweir 				if(SFX_ITEM_SET == pArgs->GetItemState(SID_TABLE_PARAM_INSERT_AFTER, sal_True, &pItem))
512*cdf0e10cSrcweir 					bInsertAfter = ((const SfxBoolItem* )pItem)->GetValue();
513*cdf0e10cSrcweir 			}
514*cdf0e10cSrcweir     	}
515*cdf0e10cSrcweir 
516*cdf0e10cSrcweir 		CellPos aStart, aEnd;
517*cdf0e10cSrcweir 		if( hasSelectedCells() )
518*cdf0e10cSrcweir 		{
519*cdf0e10cSrcweir 			getSelectedCells( aStart, aEnd );
520*cdf0e10cSrcweir 		}
521*cdf0e10cSrcweir 		else
522*cdf0e10cSrcweir 		{
523*cdf0e10cSrcweir 		    if( bInsertAfter )
524*cdf0e10cSrcweir 		    {
525*cdf0e10cSrcweir 			    aStart.mnCol = mxTable->getColumnCount() - 1;
526*cdf0e10cSrcweir 			    aStart.mnRow = mxTable->getRowCount() - 1;
527*cdf0e10cSrcweir 			    aEnd = aStart;
528*cdf0e10cSrcweir 		    }
529*cdf0e10cSrcweir 		}
530*cdf0e10cSrcweir 
531*cdf0e10cSrcweir 		if( pTableObj->IsTextEditActive() )
532*cdf0e10cSrcweir 			mpView->SdrEndTextEdit(sal_True);
533*cdf0e10cSrcweir 
534*cdf0e10cSrcweir 		RemoveSelection();
535*cdf0e10cSrcweir 
536*cdf0e10cSrcweir 		const OUString sSize( RTL_CONSTASCII_USTRINGPARAM( "Size" ) );
537*cdf0e10cSrcweir 
538*cdf0e10cSrcweir 		const bool bUndo = mpModel && mpModel->IsUndoEnabled();
539*cdf0e10cSrcweir 
540*cdf0e10cSrcweir 		switch( nSId )
541*cdf0e10cSrcweir 		{
542*cdf0e10cSrcweir 		case SID_TABLE_INSERT_COL:
543*cdf0e10cSrcweir 		{
544*cdf0e10cSrcweir 			TableModelNotifyGuard aGuard( mxTable.get() );
545*cdf0e10cSrcweir 
546*cdf0e10cSrcweir 			if( bUndo )
547*cdf0e10cSrcweir 			{
548*cdf0e10cSrcweir 				mpModel->BegUndo( ImpGetResStr(STR_TABLE_INSCOL) );
549*cdf0e10cSrcweir 				mpModel->AddUndo( mpModel->GetSdrUndoFactory().CreateUndoGeoObject(*pTableObj) );
550*cdf0e10cSrcweir 			}
551*cdf0e10cSrcweir 
552*cdf0e10cSrcweir 			Reference< XTableColumns > xCols( mxTable->getColumns() );
553*cdf0e10cSrcweir 			const sal_Int32 nNewColumns = (nCount == 0) ? (aEnd.mnCol - aStart.mnCol + 1) : nCount;
554*cdf0e10cSrcweir 			const sal_Int32 nNewStartColumn = aEnd.mnCol + (bInsertAfter ? 1 : 0);
555*cdf0e10cSrcweir 			xCols->insertByIndex( nNewStartColumn, nNewColumns );
556*cdf0e10cSrcweir 
557*cdf0e10cSrcweir 			for( sal_Int32 nOffset = 0; nOffset < nNewColumns; nOffset++ )
558*cdf0e10cSrcweir 			{
559*cdf0e10cSrcweir 				Reference< XPropertySet >( xCols->getByIndex( aEnd.mnCol + nOffset + 1 ), UNO_QUERY_THROW )->
560*cdf0e10cSrcweir 					setPropertyValue( sSize,
561*cdf0e10cSrcweir 						Reference< XPropertySet >( xCols->getByIndex( aStart.mnCol + nOffset ), UNO_QUERY_THROW )->
562*cdf0e10cSrcweir 							getPropertyValue( sSize ) );
563*cdf0e10cSrcweir 			}
564*cdf0e10cSrcweir 
565*cdf0e10cSrcweir 			if( bUndo )
566*cdf0e10cSrcweir 				mpModel->EndUndo();
567*cdf0e10cSrcweir 
568*cdf0e10cSrcweir 			aStart.mnCol = nNewStartColumn;
569*cdf0e10cSrcweir 			aStart.mnRow = 0;
570*cdf0e10cSrcweir 			aEnd.mnCol = aStart.mnCol + nNewColumns - 1;
571*cdf0e10cSrcweir 			aEnd.mnRow = mxTable->getRowCount() - 1;
572*cdf0e10cSrcweir 			break;
573*cdf0e10cSrcweir 		}
574*cdf0e10cSrcweir 
575*cdf0e10cSrcweir 		case SID_TABLE_INSERT_ROW:
576*cdf0e10cSrcweir 		{
577*cdf0e10cSrcweir 			TableModelNotifyGuard aGuard( mxTable.get() );
578*cdf0e10cSrcweir 
579*cdf0e10cSrcweir 			if( bUndo )
580*cdf0e10cSrcweir 			{
581*cdf0e10cSrcweir 				mpModel->BegUndo( ImpGetResStr(STR_TABLE_INSROW ) );
582*cdf0e10cSrcweir 				mpModel->AddUndo( mpModel->GetSdrUndoFactory().CreateUndoGeoObject(*pTableObj) );
583*cdf0e10cSrcweir 			}
584*cdf0e10cSrcweir 
585*cdf0e10cSrcweir 			Reference< XTableRows > xRows( mxTable->getRows() );
586*cdf0e10cSrcweir 			const sal_Int32 nNewRows = (nCount == 0) ? (aEnd.mnRow - aStart.mnRow + 1) : nCount;
587*cdf0e10cSrcweir 			const sal_Int32 nNewRowStart = aEnd.mnRow + (bInsertAfter ? 1 : 0);
588*cdf0e10cSrcweir 			xRows->insertByIndex( nNewRowStart, nNewRows );
589*cdf0e10cSrcweir 
590*cdf0e10cSrcweir 			for( sal_Int32 nOffset = 0; nOffset < nNewRows; nOffset++ )
591*cdf0e10cSrcweir 			{
592*cdf0e10cSrcweir 				Reference< XPropertySet >( xRows->getByIndex( aEnd.mnRow + nOffset + 1 ), UNO_QUERY_THROW )->
593*cdf0e10cSrcweir 					setPropertyValue( sSize,
594*cdf0e10cSrcweir 						Reference< XPropertySet >( xRows->getByIndex( aStart.mnRow + nOffset ), UNO_QUERY_THROW )->
595*cdf0e10cSrcweir 							getPropertyValue( sSize ) );
596*cdf0e10cSrcweir 			}
597*cdf0e10cSrcweir 
598*cdf0e10cSrcweir 			if( bUndo )
599*cdf0e10cSrcweir 				mpModel->EndUndo();
600*cdf0e10cSrcweir 
601*cdf0e10cSrcweir 			aStart.mnCol = 0;
602*cdf0e10cSrcweir 			aStart.mnRow = nNewRowStart;
603*cdf0e10cSrcweir 			aEnd.mnCol = mxTable->getColumnCount() - 1;
604*cdf0e10cSrcweir 			aEnd.mnRow = aStart.mnRow + nNewRows - 1;
605*cdf0e10cSrcweir 			break;
606*cdf0e10cSrcweir 		}
607*cdf0e10cSrcweir 		}
608*cdf0e10cSrcweir 
609*cdf0e10cSrcweir 		StartSelection( aStart );
610*cdf0e10cSrcweir 		UpdateSelection( aEnd );
611*cdf0e10cSrcweir 	}
612*cdf0e10cSrcweir 	catch( Exception& e )
613*cdf0e10cSrcweir 	{
614*cdf0e10cSrcweir 		(void)e;
615*cdf0e10cSrcweir 		DBG_ERROR("svx::SvxTableController::onInsert(), exception caught!");
616*cdf0e10cSrcweir 	}
617*cdf0e10cSrcweir }
618*cdf0e10cSrcweir 
619*cdf0e10cSrcweir // --------------------------------------------------------------------
620*cdf0e10cSrcweir 
621*cdf0e10cSrcweir void SvxTableController::onDelete( sal_uInt16 nSId )
622*cdf0e10cSrcweir {
623*cdf0e10cSrcweir 	::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
624*cdf0e10cSrcweir 	if( !pTableObj )
625*cdf0e10cSrcweir 		return;
626*cdf0e10cSrcweir 
627*cdf0e10cSrcweir 	if( mxTable.is() && hasSelectedCells() )
628*cdf0e10cSrcweir 	{
629*cdf0e10cSrcweir 		CellPos aStart, aEnd;
630*cdf0e10cSrcweir 		getSelectedCells( aStart, aEnd );
631*cdf0e10cSrcweir 
632*cdf0e10cSrcweir 		if( pTableObj->IsTextEditActive() )
633*cdf0e10cSrcweir 			mpView->SdrEndTextEdit(sal_True);
634*cdf0e10cSrcweir 
635*cdf0e10cSrcweir 		RemoveSelection();
636*cdf0e10cSrcweir 
637*cdf0e10cSrcweir 		bool bDeleteTable = false;
638*cdf0e10cSrcweir 		switch( nSId )
639*cdf0e10cSrcweir 		{
640*cdf0e10cSrcweir 		case SID_TABLE_DELETE_COL:
641*cdf0e10cSrcweir 		{
642*cdf0e10cSrcweir 			const sal_Int32 nRemovedColumns = aEnd.mnCol - aStart.mnCol + 1;
643*cdf0e10cSrcweir 			if( nRemovedColumns == mxTable->getColumnCount() )
644*cdf0e10cSrcweir 			{
645*cdf0e10cSrcweir 				bDeleteTable = true;
646*cdf0e10cSrcweir 			}
647*cdf0e10cSrcweir 			else
648*cdf0e10cSrcweir 			{
649*cdf0e10cSrcweir 				Reference< XTableColumns > xCols( mxTable->getColumns() );
650*cdf0e10cSrcweir 				xCols->removeByIndex( aStart.mnCol, nRemovedColumns );
651*cdf0e10cSrcweir 			}
652*cdf0e10cSrcweir 			break;
653*cdf0e10cSrcweir 		}
654*cdf0e10cSrcweir 
655*cdf0e10cSrcweir 		case SID_TABLE_DELETE_ROW:
656*cdf0e10cSrcweir 		{
657*cdf0e10cSrcweir 			const sal_Int32 nRemovedRows = aEnd.mnRow - aStart.mnRow + 1;
658*cdf0e10cSrcweir 			if( nRemovedRows == mxTable->getRowCount() )
659*cdf0e10cSrcweir 			{
660*cdf0e10cSrcweir 				bDeleteTable = true;
661*cdf0e10cSrcweir 			}
662*cdf0e10cSrcweir 			else
663*cdf0e10cSrcweir 			{
664*cdf0e10cSrcweir 				Reference< XTableRows > xRows( mxTable->getRows() );
665*cdf0e10cSrcweir 				xRows->removeByIndex( aStart.mnRow, nRemovedRows );
666*cdf0e10cSrcweir 			}
667*cdf0e10cSrcweir 			break;
668*cdf0e10cSrcweir 		}
669*cdf0e10cSrcweir 		}
670*cdf0e10cSrcweir 
671*cdf0e10cSrcweir 		if( bDeleteTable )
672*cdf0e10cSrcweir 			mpView->DeleteMarkedObj();
673*cdf0e10cSrcweir 		else
674*cdf0e10cSrcweir 			UpdateTableShape();
675*cdf0e10cSrcweir 	}
676*cdf0e10cSrcweir }
677*cdf0e10cSrcweir 
678*cdf0e10cSrcweir // --------------------------------------------------------------------
679*cdf0e10cSrcweir 
680*cdf0e10cSrcweir void SvxTableController::onSelect( sal_uInt16 nSId )
681*cdf0e10cSrcweir {
682*cdf0e10cSrcweir 	if( mxTable.is() )
683*cdf0e10cSrcweir 	{
684*cdf0e10cSrcweir 		const sal_Int32 nRowCount = mxTable->getRowCount();
685*cdf0e10cSrcweir 		const sal_Int32 nColCount = mxTable->getColumnCount();
686*cdf0e10cSrcweir 		if( nRowCount && nColCount )
687*cdf0e10cSrcweir 		{
688*cdf0e10cSrcweir 			CellPos aStart, aEnd;
689*cdf0e10cSrcweir 			getSelectedCells( aStart, aEnd );
690*cdf0e10cSrcweir 
691*cdf0e10cSrcweir 			switch( nSId )
692*cdf0e10cSrcweir 			{
693*cdf0e10cSrcweir 			case SID_TABLE_SELECT_ALL:
694*cdf0e10cSrcweir 				aEnd.mnCol = 0; aEnd.mnRow = 0;
695*cdf0e10cSrcweir 				aStart.mnCol = nColCount - 1; aStart.mnRow = nRowCount - 1;
696*cdf0e10cSrcweir 				break;
697*cdf0e10cSrcweir 			case SID_TABLE_SELECT_COL:
698*cdf0e10cSrcweir 				aEnd.mnRow = nRowCount - 1;
699*cdf0e10cSrcweir 				aStart.mnRow = 0;
700*cdf0e10cSrcweir 				break;
701*cdf0e10cSrcweir 			case SID_TABLE_SELECT_ROW:
702*cdf0e10cSrcweir 				aEnd.mnCol = nColCount - 1;
703*cdf0e10cSrcweir 				aStart.mnCol = 0;
704*cdf0e10cSrcweir 				break;
705*cdf0e10cSrcweir 			}
706*cdf0e10cSrcweir 
707*cdf0e10cSrcweir 			StartSelection( aEnd );
708*cdf0e10cSrcweir 			gotoCell( aStart, true, 0 );
709*cdf0e10cSrcweir 		}
710*cdf0e10cSrcweir 	}
711*cdf0e10cSrcweir }
712*cdf0e10cSrcweir 
713*cdf0e10cSrcweir // --------------------------------------------------------------------
714*cdf0e10cSrcweir void SvxTableController::onFormatTable( SfxRequest& rReq )
715*cdf0e10cSrcweir {
716*cdf0e10cSrcweir 	::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
717*cdf0e10cSrcweir 	if( !pTableObj )
718*cdf0e10cSrcweir 		return;
719*cdf0e10cSrcweir 
720*cdf0e10cSrcweir 	const SfxItemSet* pArgs = rReq.GetArgs();
721*cdf0e10cSrcweir 
722*cdf0e10cSrcweir 	if( !pArgs && pTableObj->GetModel() )
723*cdf0e10cSrcweir 	{
724*cdf0e10cSrcweir 		SfxItemSet aNewAttr( pTableObj->GetModel()->GetItemPool() );
725*cdf0e10cSrcweir 		MergeAttrFromSelectedCells(aNewAttr, sal_False);
726*cdf0e10cSrcweir 
727*cdf0e10cSrcweir 		// merge drawing layer text distance items into SvxBoxItem used by the dialog
728*cdf0e10cSrcweir 		SvxBoxItem aBoxItem( static_cast< const SvxBoxItem& >( aNewAttr.Get( SDRATTR_TABLE_BORDER ) ) );
729*cdf0e10cSrcweir 		aBoxItem.SetDistance( sal::static_int_cast< sal_uInt16 >( ((SdrTextLeftDistItem&)(aNewAttr.Get(SDRATTR_TEXT_LEFTDIST))).GetValue()), BOX_LINE_LEFT );
730*cdf0e10cSrcweir 		aBoxItem.SetDistance( sal::static_int_cast< sal_uInt16 >( ((SdrTextRightDistItem&)(aNewAttr.Get(SDRATTR_TEXT_RIGHTDIST))).GetValue()), BOX_LINE_RIGHT );
731*cdf0e10cSrcweir 		aBoxItem.SetDistance( sal::static_int_cast< sal_uInt16 >( ((SdrTextUpperDistItem&)(aNewAttr.Get(SDRATTR_TEXT_UPPERDIST))).GetValue()), BOX_LINE_TOP );
732*cdf0e10cSrcweir 		aBoxItem.SetDistance( sal::static_int_cast< sal_uInt16 >( ((SdrTextLowerDistItem&)(aNewAttr.Get(SDRATTR_TEXT_LOWERDIST))).GetValue()), BOX_LINE_BOTTOM );
733*cdf0e10cSrcweir 		aNewAttr.Put( aBoxItem );
734*cdf0e10cSrcweir 
735*cdf0e10cSrcweir 		SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
736*cdf0e10cSrcweir 		std::auto_ptr< SfxAbstractTabDialog > pDlg( pFact ? pFact->CreateSvxFormatCellsDialog( NULL, &aNewAttr, pTableObj->GetModel(), pTableObj) : 0 );
737*cdf0e10cSrcweir 		if( pDlg.get() && pDlg->Execute() )
738*cdf0e10cSrcweir 		{
739*cdf0e10cSrcweir 			SfxItemSet aNewSet( *(pDlg->GetOutputItemSet ()) );
740*cdf0e10cSrcweir 
741*cdf0e10cSrcweir 			SvxBoxItem aNewBoxItem( static_cast< const SvxBoxItem& >( aNewSet.Get( SDRATTR_TABLE_BORDER ) ) );
742*cdf0e10cSrcweir 
743*cdf0e10cSrcweir 			if( aNewBoxItem.GetDistance( BOX_LINE_LEFT ) != aBoxItem.GetDistance( BOX_LINE_LEFT ) )
744*cdf0e10cSrcweir 				aNewSet.Put(SdrTextLeftDistItem( aNewBoxItem.GetDistance( BOX_LINE_LEFT ) ) );
745*cdf0e10cSrcweir 
746*cdf0e10cSrcweir 			if( aNewBoxItem.GetDistance( BOX_LINE_RIGHT ) != aBoxItem.GetDistance( BOX_LINE_RIGHT ) )
747*cdf0e10cSrcweir 				aNewSet.Put(SdrTextRightDistItem( aNewBoxItem.GetDistance( BOX_LINE_RIGHT ) ) );
748*cdf0e10cSrcweir 
749*cdf0e10cSrcweir 			if( aNewBoxItem.GetDistance( BOX_LINE_TOP ) != aBoxItem.GetDistance( BOX_LINE_TOP ) )
750*cdf0e10cSrcweir 				aNewSet.Put(SdrTextUpperDistItem( aNewBoxItem.GetDistance( BOX_LINE_TOP ) ) );
751*cdf0e10cSrcweir 
752*cdf0e10cSrcweir 			if( aNewBoxItem.GetDistance( BOX_LINE_BOTTOM ) != aBoxItem.GetDistance( BOX_LINE_BOTTOM ) )
753*cdf0e10cSrcweir 				aNewSet.Put(SdrTextLowerDistItem( aNewBoxItem.GetDistance( BOX_LINE_BOTTOM ) ) );
754*cdf0e10cSrcweir 
755*cdf0e10cSrcweir 			SetAttrToSelectedCells(aNewSet, sal_False);
756*cdf0e10cSrcweir 		}
757*cdf0e10cSrcweir 		UpdateTableShape();
758*cdf0e10cSrcweir 	}
759*cdf0e10cSrcweir }
760*cdf0e10cSrcweir 
761*cdf0e10cSrcweir // --------------------------------------------------------------------
762*cdf0e10cSrcweir 
763*cdf0e10cSrcweir void SvxTableController::Execute( SfxRequest& rReq )
764*cdf0e10cSrcweir {
765*cdf0e10cSrcweir 	const sal_uInt16 nSId = rReq.GetSlot();
766*cdf0e10cSrcweir 	switch( nSId )
767*cdf0e10cSrcweir 	{
768*cdf0e10cSrcweir 	case SID_TABLE_INSERT_ROW:
769*cdf0e10cSrcweir 	case SID_TABLE_INSERT_COL:
770*cdf0e10cSrcweir 		onInsert( nSId, rReq.GetArgs() );
771*cdf0e10cSrcweir 		break;
772*cdf0e10cSrcweir 	case SID_TABLE_DELETE_ROW:
773*cdf0e10cSrcweir 	case SID_TABLE_DELETE_COL:
774*cdf0e10cSrcweir 		onDelete( nSId );
775*cdf0e10cSrcweir 		break;
776*cdf0e10cSrcweir 	case SID_TABLE_SELECT_ALL:
777*cdf0e10cSrcweir 	case SID_TABLE_SELECT_COL:
778*cdf0e10cSrcweir 	case SID_TABLE_SELECT_ROW:
779*cdf0e10cSrcweir 		onSelect( nSId );
780*cdf0e10cSrcweir 		break;
781*cdf0e10cSrcweir 	case SID_FORMAT_TABLE_DLG:
782*cdf0e10cSrcweir 		onFormatTable( rReq );
783*cdf0e10cSrcweir 		break;
784*cdf0e10cSrcweir 
785*cdf0e10cSrcweir 	case SID_FRAME_LINESTYLE:
786*cdf0e10cSrcweir 	case SID_FRAME_LINECOLOR:
787*cdf0e10cSrcweir 	case SID_ATTR_BORDER:
788*cdf0e10cSrcweir 		{
789*cdf0e10cSrcweir 			const SfxItemSet* pArgs = rReq.GetArgs();
790*cdf0e10cSrcweir 			if( pArgs )
791*cdf0e10cSrcweir 				ApplyBorderAttr( *pArgs );
792*cdf0e10cSrcweir 		}
793*cdf0e10cSrcweir 		break;
794*cdf0e10cSrcweir 
795*cdf0e10cSrcweir 	case SID_ATTR_FILL_STYLE:
796*cdf0e10cSrcweir 		{
797*cdf0e10cSrcweir 			const SfxItemSet* pArgs = rReq.GetArgs();
798*cdf0e10cSrcweir 			if( pArgs )
799*cdf0e10cSrcweir 				SetAttributes( *pArgs, false );
800*cdf0e10cSrcweir 		}
801*cdf0e10cSrcweir 		break;
802*cdf0e10cSrcweir 
803*cdf0e10cSrcweir 	case SID_TABLE_MERGE_CELLS:
804*cdf0e10cSrcweir 		MergeMarkedCells();
805*cdf0e10cSrcweir 		break;
806*cdf0e10cSrcweir 
807*cdf0e10cSrcweir 	case SID_TABLE_SPLIT_CELLS:
808*cdf0e10cSrcweir 		SplitMarkedCells();
809*cdf0e10cSrcweir 		break;
810*cdf0e10cSrcweir 
811*cdf0e10cSrcweir 	case SID_TABLE_DISTRIBUTE_COLUMNS:
812*cdf0e10cSrcweir 		DistributeColumns();
813*cdf0e10cSrcweir 		break;
814*cdf0e10cSrcweir 
815*cdf0e10cSrcweir 	case SID_TABLE_DISTRIBUTE_ROWS:
816*cdf0e10cSrcweir 		DistributeRows();
817*cdf0e10cSrcweir 		break;
818*cdf0e10cSrcweir 
819*cdf0e10cSrcweir 	case SID_TABLE_VERT_BOTTOM:
820*cdf0e10cSrcweir 	case SID_TABLE_VERT_CENTER:
821*cdf0e10cSrcweir 	case SID_TABLE_VERT_NONE:
822*cdf0e10cSrcweir 		SetVertical( nSId );
823*cdf0e10cSrcweir 		break;
824*cdf0e10cSrcweir 
825*cdf0e10cSrcweir 	case SID_AUTOFORMAT:
826*cdf0e10cSrcweir 	case SID_TABLE_SORT_DIALOG:
827*cdf0e10cSrcweir 	case SID_TABLE_AUTOSUM:
828*cdf0e10cSrcweir 	default:
829*cdf0e10cSrcweir 		break;
830*cdf0e10cSrcweir 
831*cdf0e10cSrcweir 	case SID_TABLE_STYLE:
832*cdf0e10cSrcweir 		SetTableStyle( rReq.GetArgs() );
833*cdf0e10cSrcweir 		break;
834*cdf0e10cSrcweir 
835*cdf0e10cSrcweir 	case SID_TABLE_STYLE_SETTINGS:
836*cdf0e10cSrcweir 		SetTableStyleSettings( rReq.GetArgs() );
837*cdf0e10cSrcweir 		break;
838*cdf0e10cSrcweir 	}
839*cdf0e10cSrcweir }
840*cdf0e10cSrcweir 
841*cdf0e10cSrcweir void SvxTableController::SetTableStyle( const SfxItemSet* pArgs )
842*cdf0e10cSrcweir {
843*cdf0e10cSrcweir 	SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
844*cdf0e10cSrcweir 	SdrModel* pModel = pTableObj ? pTableObj->GetModel() : 0;
845*cdf0e10cSrcweir 
846*cdf0e10cSrcweir 	if( !pTableObj || !pModel || !pArgs || (SFX_ITEM_SET != pArgs->GetItemState(SID_TABLE_STYLE, sal_False)) )
847*cdf0e10cSrcweir 		return;
848*cdf0e10cSrcweir 
849*cdf0e10cSrcweir 	const SfxStringItem* pArg = dynamic_cast< const SfxStringItem* >( &pArgs->Get( SID_TABLE_STYLE ) );
850*cdf0e10cSrcweir 	if( pArg && mxTable.is() ) try
851*cdf0e10cSrcweir 	{
852*cdf0e10cSrcweir 		Reference< XStyleFamiliesSupplier > xSFS( pModel->getUnoModel(), UNO_QUERY_THROW );
853*cdf0e10cSrcweir 		Reference< XNameAccess > xFamilyNameAccess( xSFS->getStyleFamilies(), UNO_QUERY_THROW );
854*cdf0e10cSrcweir 		const OUString sFamilyName( RTL_CONSTASCII_USTRINGPARAM( "table" ) );
855*cdf0e10cSrcweir 		Reference< XNameAccess > xTableFamilyAccess( xFamilyNameAccess->getByName( sFamilyName ), UNO_QUERY_THROW );
856*cdf0e10cSrcweir 
857*cdf0e10cSrcweir 		if( xTableFamilyAccess->hasByName( pArg->GetValue() ) )
858*cdf0e10cSrcweir 		{
859*cdf0e10cSrcweir 			// found table style with the same name
860*cdf0e10cSrcweir 			Reference< XIndexAccess > xNewTableStyle( xTableFamilyAccess->getByName( pArg->GetValue() ), UNO_QUERY_THROW );
861*cdf0e10cSrcweir 
862*cdf0e10cSrcweir 			const bool bUndo = pModel->IsUndoEnabled();
863*cdf0e10cSrcweir 
864*cdf0e10cSrcweir 			if( bUndo )
865*cdf0e10cSrcweir 			{
866*cdf0e10cSrcweir 				pModel->BegUndo( ImpGetResStr(STR_TABLE_STYLE) );
867*cdf0e10cSrcweir 				pModel->AddUndo( new TableStyleUndo( *pTableObj ) );
868*cdf0e10cSrcweir 			}
869*cdf0e10cSrcweir 
870*cdf0e10cSrcweir 			pTableObj->setTableStyle( xNewTableStyle );
871*cdf0e10cSrcweir 
872*cdf0e10cSrcweir 			const sal_Int32 nRowCount = mxTable->getRowCount();
873*cdf0e10cSrcweir 			const sal_Int32 nColCount = mxTable->getColumnCount();
874*cdf0e10cSrcweir 			for( sal_Int32 nRow = 0; nRow < nRowCount; nRow++ )
875*cdf0e10cSrcweir 			{
876*cdf0e10cSrcweir 				for( sal_Int32 nCol = 0; nCol < nColCount; nCol++ ) try
877*cdf0e10cSrcweir 				{
878*cdf0e10cSrcweir 					CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
879*cdf0e10cSrcweir 					if( xCell.is() )
880*cdf0e10cSrcweir 					{
881*cdf0e10cSrcweir                         SfxItemSet aSet( xCell->GetItemSet() );
882*cdf0e10cSrcweir                         bool bChanges = false;
883*cdf0e10cSrcweir 	                    const SfxItemSet& rStyleAttribs = xCell->GetStyleSheet()->GetItemSet();
884*cdf0e10cSrcweir 
885*cdf0e10cSrcweir 	                    for ( sal_uInt16 nWhich = SDRATTR_START; nWhich <= SDRATTR_TABLE_LAST; nWhich++ )
886*cdf0e10cSrcweir 	                    {
887*cdf0e10cSrcweir 		                    if( (rStyleAttribs.GetItemState( nWhich ) == SFX_ITEM_ON) && (aSet.GetItemState( nWhich ) == SFX_ITEM_ON) )
888*cdf0e10cSrcweir 		                    {
889*cdf0e10cSrcweir 			                    aSet.ClearItem( nWhich );
890*cdf0e10cSrcweir 			                    bChanges = true;
891*cdf0e10cSrcweir 			                }
892*cdf0e10cSrcweir 	                    }
893*cdf0e10cSrcweir 
894*cdf0e10cSrcweir 	                    if( bChanges )
895*cdf0e10cSrcweir 	                    {
896*cdf0e10cSrcweir 						    if( bUndo )
897*cdf0e10cSrcweir 							    xCell->AddUndo();
898*cdf0e10cSrcweir 
899*cdf0e10cSrcweir 							xCell->SetMergedItemSetAndBroadcast( aSet, sal_True );
900*cdf0e10cSrcweir 	                    }
901*cdf0e10cSrcweir                     }
902*cdf0e10cSrcweir 				}
903*cdf0e10cSrcweir 				catch( Exception& e )
904*cdf0e10cSrcweir 				{
905*cdf0e10cSrcweir 					(void)e;
906*cdf0e10cSrcweir 					DBG_ERROR( "svx::SvxTableController::SetTableStyle(), exception caught!" );
907*cdf0e10cSrcweir 				}
908*cdf0e10cSrcweir 			}
909*cdf0e10cSrcweir 
910*cdf0e10cSrcweir 			if( bUndo )
911*cdf0e10cSrcweir 				pModel->EndUndo();
912*cdf0e10cSrcweir 		}
913*cdf0e10cSrcweir 	}
914*cdf0e10cSrcweir 	catch( Exception& e )
915*cdf0e10cSrcweir 	{
916*cdf0e10cSrcweir 		(void)e;
917*cdf0e10cSrcweir 		DBG_ERROR( "svx::SvxTableController::SetTableStyle(), exception caught!" );
918*cdf0e10cSrcweir 	}
919*cdf0e10cSrcweir }
920*cdf0e10cSrcweir 
921*cdf0e10cSrcweir void SvxTableController::SetTableStyleSettings( const SfxItemSet* pArgs )
922*cdf0e10cSrcweir {
923*cdf0e10cSrcweir 	SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
924*cdf0e10cSrcweir 	SdrModel* pModel = pTableObj ? pTableObj->GetModel() : 0;
925*cdf0e10cSrcweir 
926*cdf0e10cSrcweir 	if( !pTableObj || !pModel )
927*cdf0e10cSrcweir 		return;
928*cdf0e10cSrcweir 
929*cdf0e10cSrcweir 	TableStyleSettings aSettings( pTableObj->getTableStyleSettings() );
930*cdf0e10cSrcweir 
931*cdf0e10cSrcweir 	const SfxPoolItem *pPoolItem=NULL;
932*cdf0e10cSrcweir 
933*cdf0e10cSrcweir 	if( (SFX_ITEM_SET == pArgs->GetItemState(ID_VAL_USEFIRSTROWSTYLE, sal_False,&pPoolItem)) )
934*cdf0e10cSrcweir 		aSettings.mbUseFirstRow = static_cast< const SfxBoolItem* >(pPoolItem)->GetValue();
935*cdf0e10cSrcweir 
936*cdf0e10cSrcweir 	if( (SFX_ITEM_SET == pArgs->GetItemState(ID_VAL_USELASTROWSTYLE, sal_False,&pPoolItem)) )
937*cdf0e10cSrcweir 		aSettings.mbUseLastRow = static_cast< const SfxBoolItem* >(pPoolItem)->GetValue();
938*cdf0e10cSrcweir 
939*cdf0e10cSrcweir 	if( (SFX_ITEM_SET == pArgs->GetItemState(ID_VAL_USEBANDINGROWSTYLE, sal_False,&pPoolItem)) )
940*cdf0e10cSrcweir 		aSettings.mbUseRowBanding = static_cast< const SfxBoolItem* >(pPoolItem)->GetValue();
941*cdf0e10cSrcweir 
942*cdf0e10cSrcweir 	if( (SFX_ITEM_SET == pArgs->GetItemState(ID_VAL_USEFIRSTCOLUMNSTYLE, sal_False,&pPoolItem)) )
943*cdf0e10cSrcweir 		aSettings.mbUseFirstColumn = static_cast< const SfxBoolItem* >(pPoolItem)->GetValue();
944*cdf0e10cSrcweir 
945*cdf0e10cSrcweir 	if( (SFX_ITEM_SET == pArgs->GetItemState(ID_VAL_USELASTCOLUMNSTYLE, sal_False,&pPoolItem)) )
946*cdf0e10cSrcweir 		aSettings.mbUseLastColumn = static_cast< const SfxBoolItem* >(pPoolItem)->GetValue();
947*cdf0e10cSrcweir 
948*cdf0e10cSrcweir 	if( (SFX_ITEM_SET == pArgs->GetItemState(ID_VAL_USEBANDINGCOLUMNSTYLE, sal_False,&pPoolItem)) )
949*cdf0e10cSrcweir 		aSettings.mbUseColumnBanding = static_cast< const SfxBoolItem* >(pPoolItem)->GetValue();
950*cdf0e10cSrcweir 
951*cdf0e10cSrcweir 	if( aSettings == pTableObj->getTableStyleSettings() )
952*cdf0e10cSrcweir 		return;
953*cdf0e10cSrcweir 
954*cdf0e10cSrcweir 	const bool bUndo = pModel->IsUndoEnabled();
955*cdf0e10cSrcweir 
956*cdf0e10cSrcweir 	if( bUndo )
957*cdf0e10cSrcweir 	{
958*cdf0e10cSrcweir 		pModel->BegUndo( ImpGetResStr(STR_TABLE_STYLE_SETTINGS) );
959*cdf0e10cSrcweir 		pModel->AddUndo( new TableStyleUndo( *pTableObj ) );
960*cdf0e10cSrcweir 	}
961*cdf0e10cSrcweir 
962*cdf0e10cSrcweir 	pTableObj->setTableStyleSettings( aSettings );
963*cdf0e10cSrcweir 
964*cdf0e10cSrcweir 	if( bUndo )
965*cdf0e10cSrcweir 		pModel->EndUndo();
966*cdf0e10cSrcweir }
967*cdf0e10cSrcweir 
968*cdf0e10cSrcweir void SvxTableController::SetVertical( sal_uInt16 nSId )
969*cdf0e10cSrcweir {
970*cdf0e10cSrcweir 	SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
971*cdf0e10cSrcweir 	if( mxTable.is() && pTableObj )
972*cdf0e10cSrcweir 	{
973*cdf0e10cSrcweir 		TableModelNotifyGuard aGuard( mxTable.get() );
974*cdf0e10cSrcweir 
975*cdf0e10cSrcweir 		CellPos aStart, aEnd;
976*cdf0e10cSrcweir 		getSelectedCells( aStart, aEnd );
977*cdf0e10cSrcweir 
978*cdf0e10cSrcweir 		SdrTextVertAdjust eAdj = SDRTEXTVERTADJUST_TOP;
979*cdf0e10cSrcweir 
980*cdf0e10cSrcweir 		switch( nSId )
981*cdf0e10cSrcweir 		{
982*cdf0e10cSrcweir 			case SID_TABLE_VERT_BOTTOM:
983*cdf0e10cSrcweir 				eAdj = SDRTEXTVERTADJUST_BOTTOM;
984*cdf0e10cSrcweir 				break;
985*cdf0e10cSrcweir 			case SID_TABLE_VERT_CENTER:
986*cdf0e10cSrcweir 				eAdj = SDRTEXTVERTADJUST_CENTER;
987*cdf0e10cSrcweir 				break;
988*cdf0e10cSrcweir 			//case SID_TABLE_VERT_NONE:
989*cdf0e10cSrcweir 			default:
990*cdf0e10cSrcweir 				break;
991*cdf0e10cSrcweir 		}
992*cdf0e10cSrcweir 
993*cdf0e10cSrcweir 		SdrTextVertAdjustItem aItem( eAdj );
994*cdf0e10cSrcweir 
995*cdf0e10cSrcweir 		for( sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++ )
996*cdf0e10cSrcweir 		{
997*cdf0e10cSrcweir 			for( sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++ )
998*cdf0e10cSrcweir 			{
999*cdf0e10cSrcweir 				CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
1000*cdf0e10cSrcweir 				if( xCell.is() )
1001*cdf0e10cSrcweir 					xCell->SetMergedItem(aItem);
1002*cdf0e10cSrcweir 			}
1003*cdf0e10cSrcweir 		}
1004*cdf0e10cSrcweir 
1005*cdf0e10cSrcweir 		UpdateTableShape();
1006*cdf0e10cSrcweir 	}
1007*cdf0e10cSrcweir }
1008*cdf0e10cSrcweir 
1009*cdf0e10cSrcweir void SvxTableController::MergeMarkedCells()
1010*cdf0e10cSrcweir {
1011*cdf0e10cSrcweir 	CellPos aStart, aEnd;
1012*cdf0e10cSrcweir 	getSelectedCells( aStart, aEnd );
1013*cdf0e10cSrcweir 	SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
1014*cdf0e10cSrcweir 	if( pTableObj )
1015*cdf0e10cSrcweir 	{
1016*cdf0e10cSrcweir 	    if( pTableObj->IsTextEditActive() )
1017*cdf0e10cSrcweir 		    mpView->SdrEndTextEdit(sal_True);
1018*cdf0e10cSrcweir 
1019*cdf0e10cSrcweir         TableModelNotifyGuard aGuard( mxTable.get() );
1020*cdf0e10cSrcweir 		MergeRange( aStart.mnCol, aStart.mnRow, aEnd.mnCol, aEnd.mnRow );
1021*cdf0e10cSrcweir 	}
1022*cdf0e10cSrcweir }
1023*cdf0e10cSrcweir 
1024*cdf0e10cSrcweir void SvxTableController::SplitMarkedCells()
1025*cdf0e10cSrcweir {
1026*cdf0e10cSrcweir 	if( mxTable.is() )
1027*cdf0e10cSrcweir 	{
1028*cdf0e10cSrcweir 		CellPos aStart, aEnd;
1029*cdf0e10cSrcweir 		getSelectedCells( aStart, aEnd );
1030*cdf0e10cSrcweir 
1031*cdf0e10cSrcweir 		SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
1032*cdf0e10cSrcweir 		std::auto_ptr< SvxAbstractSplittTableDialog > xDlg( pFact ? pFact->CreateSvxSplittTableDialog( NULL, false, 99, 99 ) : 0 );
1033*cdf0e10cSrcweir 		if( xDlg.get() && xDlg->Execute() )
1034*cdf0e10cSrcweir 		{
1035*cdf0e10cSrcweir 			const sal_Int32 nCount = xDlg->GetCount() - 1;
1036*cdf0e10cSrcweir 			if( nCount < 1 )
1037*cdf0e10cSrcweir 				return;
1038*cdf0e10cSrcweir 
1039*cdf0e10cSrcweir 			getSelectedCells( aStart, aEnd );
1040*cdf0e10cSrcweir 
1041*cdf0e10cSrcweir 			Reference< XMergeableCellRange > xRange( mxTable->createCursorByRange( mxTable->getCellRangeByPosition( aStart.mnCol, aStart.mnRow, aEnd.mnCol, aEnd.mnRow ) ), UNO_QUERY_THROW );
1042*cdf0e10cSrcweir 
1043*cdf0e10cSrcweir 			const sal_Int32 nRowCount = mxTable->getRowCount();
1044*cdf0e10cSrcweir 			const sal_Int32 nColCount = mxTable->getColumnCount();
1045*cdf0e10cSrcweir 
1046*cdf0e10cSrcweir 
1047*cdf0e10cSrcweir 			SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >( mxTableObj.get() );
1048*cdf0e10cSrcweir 			if( pTableObj )
1049*cdf0e10cSrcweir 			{
1050*cdf0e10cSrcweir         	    if( pTableObj->IsTextEditActive() )
1051*cdf0e10cSrcweir 		            mpView->SdrEndTextEdit(sal_True);
1052*cdf0e10cSrcweir 
1053*cdf0e10cSrcweir                 TableModelNotifyGuard aGuard( mxTable.get() );
1054*cdf0e10cSrcweir 
1055*cdf0e10cSrcweir 				const bool bUndo = mpModel && mpModel->IsUndoEnabled();
1056*cdf0e10cSrcweir 				if( bUndo )
1057*cdf0e10cSrcweir 				{
1058*cdf0e10cSrcweir 					mpModel->BegUndo( ImpGetResStr(STR_TABLE_SPLIT) );
1059*cdf0e10cSrcweir 					mpModel->AddUndo( mpModel->GetSdrUndoFactory().CreateUndoGeoObject(*pTableObj) );
1060*cdf0e10cSrcweir 				}
1061*cdf0e10cSrcweir 
1062*cdf0e10cSrcweir 				if( xDlg->IsHorizontal() )
1063*cdf0e10cSrcweir 				{
1064*cdf0e10cSrcweir 					xRange->split( 0, nCount );
1065*cdf0e10cSrcweir 				}
1066*cdf0e10cSrcweir 				else
1067*cdf0e10cSrcweir 				{
1068*cdf0e10cSrcweir 					xRange->split( nCount, 0 );
1069*cdf0e10cSrcweir 				}
1070*cdf0e10cSrcweir 
1071*cdf0e10cSrcweir 				if( bUndo )
1072*cdf0e10cSrcweir 					mpModel->EndUndo();
1073*cdf0e10cSrcweir 			}
1074*cdf0e10cSrcweir 			aEnd.mnRow += mxTable->getRowCount() - nRowCount;
1075*cdf0e10cSrcweir 			aEnd.mnCol += mxTable->getColumnCount() - nColCount;
1076*cdf0e10cSrcweir 
1077*cdf0e10cSrcweir 			setSelectedCells( aStart, aEnd );
1078*cdf0e10cSrcweir 		}
1079*cdf0e10cSrcweir 	}
1080*cdf0e10cSrcweir }
1081*cdf0e10cSrcweir 
1082*cdf0e10cSrcweir void SvxTableController::DistributeColumns()
1083*cdf0e10cSrcweir {
1084*cdf0e10cSrcweir 	SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >( mxTableObj.get() );
1085*cdf0e10cSrcweir 	if( pTableObj )
1086*cdf0e10cSrcweir 	{
1087*cdf0e10cSrcweir 		const bool bUndo = mpModel && mpModel->IsUndoEnabled();
1088*cdf0e10cSrcweir 		if( bUndo )
1089*cdf0e10cSrcweir 		{
1090*cdf0e10cSrcweir 			mpModel->BegUndo( ImpGetResStr(STR_TABLE_DISTRIBUTE_COLUMNS) );
1091*cdf0e10cSrcweir 			mpModel->AddUndo( mpModel->GetSdrUndoFactory().CreateUndoGeoObject(*pTableObj) );
1092*cdf0e10cSrcweir 		}
1093*cdf0e10cSrcweir 
1094*cdf0e10cSrcweir 		CellPos aStart, aEnd;
1095*cdf0e10cSrcweir 		getSelectedCells( aStart, aEnd );
1096*cdf0e10cSrcweir 		pTableObj->DistributeColumns( aStart.mnCol, aEnd.mnCol );
1097*cdf0e10cSrcweir 
1098*cdf0e10cSrcweir 		if( bUndo )
1099*cdf0e10cSrcweir 			mpModel->EndUndo();
1100*cdf0e10cSrcweir 	}
1101*cdf0e10cSrcweir }
1102*cdf0e10cSrcweir 
1103*cdf0e10cSrcweir void SvxTableController::DistributeRows()
1104*cdf0e10cSrcweir {
1105*cdf0e10cSrcweir 	SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >( mxTableObj.get() );
1106*cdf0e10cSrcweir 	if( pTableObj )
1107*cdf0e10cSrcweir 	{
1108*cdf0e10cSrcweir 		const bool bUndo = mpModel && mpModel->IsUndoEnabled();
1109*cdf0e10cSrcweir 		if( bUndo )
1110*cdf0e10cSrcweir 		{
1111*cdf0e10cSrcweir 			mpModel->BegUndo( ImpGetResStr(STR_TABLE_DISTRIBUTE_ROWS) );
1112*cdf0e10cSrcweir 			mpModel->AddUndo( mpModel->GetSdrUndoFactory().CreateUndoGeoObject(*pTableObj) );
1113*cdf0e10cSrcweir 		}
1114*cdf0e10cSrcweir 
1115*cdf0e10cSrcweir 		CellPos aStart, aEnd;
1116*cdf0e10cSrcweir 		getSelectedCells( aStart, aEnd );
1117*cdf0e10cSrcweir 		pTableObj->DistributeRows( aStart.mnRow, aEnd.mnRow );
1118*cdf0e10cSrcweir 
1119*cdf0e10cSrcweir 		if( bUndo )
1120*cdf0e10cSrcweir 			mpModel->EndUndo();
1121*cdf0e10cSrcweir 	}
1122*cdf0e10cSrcweir }
1123*cdf0e10cSrcweir 
1124*cdf0e10cSrcweir bool SvxTableController::DeleteMarked()
1125*cdf0e10cSrcweir {
1126*cdf0e10cSrcweir 	if( mbCellSelectionMode )
1127*cdf0e10cSrcweir 	{
1128*cdf0e10cSrcweir 		if( mxTable.is() )
1129*cdf0e10cSrcweir 		{
1130*cdf0e10cSrcweir 			CellPos aStart, aEnd;
1131*cdf0e10cSrcweir 			getSelectedCells( aStart, aEnd );
1132*cdf0e10cSrcweir 			for( sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++ )
1133*cdf0e10cSrcweir 			{
1134*cdf0e10cSrcweir 				for( sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++ )
1135*cdf0e10cSrcweir 				{
1136*cdf0e10cSrcweir 					CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
1137*cdf0e10cSrcweir 					if( xCell.is() )
1138*cdf0e10cSrcweir 						xCell->SetOutlinerParaObject( 0 );
1139*cdf0e10cSrcweir 				}
1140*cdf0e10cSrcweir 			}
1141*cdf0e10cSrcweir 
1142*cdf0e10cSrcweir 			UpdateTableShape();
1143*cdf0e10cSrcweir 			return true;
1144*cdf0e10cSrcweir 		}
1145*cdf0e10cSrcweir 	}
1146*cdf0e10cSrcweir 
1147*cdf0e10cSrcweir 	return false;
1148*cdf0e10cSrcweir }
1149*cdf0e10cSrcweir 
1150*cdf0e10cSrcweir bool SvxTableController::GetStyleSheet( SfxStyleSheet*& rpStyleSheet ) const
1151*cdf0e10cSrcweir {
1152*cdf0e10cSrcweir 	if( hasSelectedCells() )
1153*cdf0e10cSrcweir 	{
1154*cdf0e10cSrcweir 		rpStyleSheet = 0;
1155*cdf0e10cSrcweir 
1156*cdf0e10cSrcweir 		if( mxTable.is() )
1157*cdf0e10cSrcweir 		{
1158*cdf0e10cSrcweir 			SfxStyleSheet* pRet=0;
1159*cdf0e10cSrcweir 			bool b1st=true;
1160*cdf0e10cSrcweir 
1161*cdf0e10cSrcweir 			CellPos aStart, aEnd;
1162*cdf0e10cSrcweir 			const_cast<SvxTableController&>(*this).getSelectedCells( aStart, aEnd );
1163*cdf0e10cSrcweir 
1164*cdf0e10cSrcweir 			for( sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++ )
1165*cdf0e10cSrcweir 			{
1166*cdf0e10cSrcweir 				for( sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++ )
1167*cdf0e10cSrcweir 				{
1168*cdf0e10cSrcweir 					CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
1169*cdf0e10cSrcweir 					if( xCell.is() )
1170*cdf0e10cSrcweir 					{
1171*cdf0e10cSrcweir 						SfxStyleSheet* pSS=xCell->GetStyleSheet();
1172*cdf0e10cSrcweir 						if(b1st)
1173*cdf0e10cSrcweir 						{
1174*cdf0e10cSrcweir 							pRet=pSS;
1175*cdf0e10cSrcweir 						}
1176*cdf0e10cSrcweir 						else if(pRet != pSS)
1177*cdf0e10cSrcweir 						{
1178*cdf0e10cSrcweir 							return true;
1179*cdf0e10cSrcweir 						}
1180*cdf0e10cSrcweir 						b1st=false;
1181*cdf0e10cSrcweir 					}
1182*cdf0e10cSrcweir 				}
1183*cdf0e10cSrcweir 			}
1184*cdf0e10cSrcweir 			rpStyleSheet = pRet;
1185*cdf0e10cSrcweir 			return true;
1186*cdf0e10cSrcweir 		}
1187*cdf0e10cSrcweir 	}
1188*cdf0e10cSrcweir 	return false;
1189*cdf0e10cSrcweir }
1190*cdf0e10cSrcweir 
1191*cdf0e10cSrcweir bool SvxTableController::SetStyleSheet( SfxStyleSheet* pStyleSheet, bool bDontRemoveHardAttr )
1192*cdf0e10cSrcweir {
1193*cdf0e10cSrcweir 	if( hasSelectedCells() && (!pStyleSheet || pStyleSheet->GetFamily() == SFX_STYLE_FAMILY_FRAME) )
1194*cdf0e10cSrcweir 	{
1195*cdf0e10cSrcweir 		if( mxTable.is() )
1196*cdf0e10cSrcweir 		{
1197*cdf0e10cSrcweir 			CellPos aStart, aEnd;
1198*cdf0e10cSrcweir 			getSelectedCells( aStart, aEnd );
1199*cdf0e10cSrcweir 
1200*cdf0e10cSrcweir 			for( sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++ )
1201*cdf0e10cSrcweir 			{
1202*cdf0e10cSrcweir 				for( sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++ )
1203*cdf0e10cSrcweir 				{
1204*cdf0e10cSrcweir 					CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
1205*cdf0e10cSrcweir 					if( xCell.is() )
1206*cdf0e10cSrcweir 						xCell->SetStyleSheet(pStyleSheet,bDontRemoveHardAttr);
1207*cdf0e10cSrcweir 				}
1208*cdf0e10cSrcweir 			}
1209*cdf0e10cSrcweir 
1210*cdf0e10cSrcweir 			UpdateTableShape();
1211*cdf0e10cSrcweir 			return true;
1212*cdf0e10cSrcweir 		}
1213*cdf0e10cSrcweir 	}
1214*cdf0e10cSrcweir 	return false;
1215*cdf0e10cSrcweir }
1216*cdf0e10cSrcweir 
1217*cdf0e10cSrcweir // --------------------------------------------------------------------
1218*cdf0e10cSrcweir // internals
1219*cdf0e10cSrcweir // --------------------------------------------------------------------
1220*cdf0e10cSrcweir 
1221*cdf0e10cSrcweir bool SvxTableController::checkTableObject()
1222*cdf0e10cSrcweir {
1223*cdf0e10cSrcweir 	return mxTableObj.is();
1224*cdf0e10cSrcweir }
1225*cdf0e10cSrcweir 
1226*cdf0e10cSrcweir // --------------------------------------------------------------------
1227*cdf0e10cSrcweir 
1228*cdf0e10cSrcweir sal_uInt16 SvxTableController::getKeyboardAction( const KeyEvent& rKEvt, Window* /*pWindow*/ )
1229*cdf0e10cSrcweir {
1230*cdf0e10cSrcweir 	const bool bMod1 = rKEvt.GetKeyCode().IsMod1(); // ctrl
1231*cdf0e10cSrcweir 	const bool bMod2 = rKEvt.GetKeyCode().IsMod2() != 0; // Alt
1232*cdf0e10cSrcweir 
1233*cdf0e10cSrcweir 	const bool bTextEdit = mpView->IsTextEdit();
1234*cdf0e10cSrcweir 
1235*cdf0e10cSrcweir 	sal_uInt16 nAction = ACTION_HANDLED_BY_VIEW;
1236*cdf0e10cSrcweir 
1237*cdf0e10cSrcweir 	::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
1238*cdf0e10cSrcweir 	if( !pTableObj )
1239*cdf0e10cSrcweir 		return nAction;
1240*cdf0e10cSrcweir 
1241*cdf0e10cSrcweir 	// handle special keys
1242*cdf0e10cSrcweir 	const sal_Int16 nCode = rKEvt.GetKeyCode().GetCode();
1243*cdf0e10cSrcweir 	switch( nCode )
1244*cdf0e10cSrcweir 	{
1245*cdf0e10cSrcweir 	case awt::Key::ESCAPE:			// handle escape
1246*cdf0e10cSrcweir 	{
1247*cdf0e10cSrcweir 		if( bTextEdit )
1248*cdf0e10cSrcweir 		{
1249*cdf0e10cSrcweir 			// escape during text edit ends text edit
1250*cdf0e10cSrcweir 			nAction = ACTION_STOP_TEXT_EDIT;
1251*cdf0e10cSrcweir 		}
1252*cdf0e10cSrcweir 		if( mbCellSelectionMode )
1253*cdf0e10cSrcweir 		{
1254*cdf0e10cSrcweir 			// escape with selected cells removes selection
1255*cdf0e10cSrcweir 			nAction = ACTION_REMOVE_SELECTION;
1256*cdf0e10cSrcweir 		}
1257*cdf0e10cSrcweir 		break;
1258*cdf0e10cSrcweir 	}
1259*cdf0e10cSrcweir 	case awt::Key::RETURN:		// handle return
1260*cdf0e10cSrcweir 	{
1261*cdf0e10cSrcweir 		if( !bMod1 && !bMod2 && !bTextEdit )
1262*cdf0e10cSrcweir 		{
1263*cdf0e10cSrcweir 			// when not already editing, return starts text edit
1264*cdf0e10cSrcweir 			setSelectionStart( pTableObj->getFirstCell() );
1265*cdf0e10cSrcweir 			nAction = ACTION_EDIT_CELL;
1266*cdf0e10cSrcweir 		}
1267*cdf0e10cSrcweir 		break;
1268*cdf0e10cSrcweir 	}
1269*cdf0e10cSrcweir 	case awt::Key::F2:			// f2 toggles text edit
1270*cdf0e10cSrcweir 	{
1271*cdf0e10cSrcweir 		if( bMod1 || bMod2 )	// f2 with modifiers is handled by the view
1272*cdf0e10cSrcweir 		{
1273*cdf0e10cSrcweir 		}
1274*cdf0e10cSrcweir 		else if( bTextEdit )
1275*cdf0e10cSrcweir 		{
1276*cdf0e10cSrcweir 			// f2 during text edit stops text edit
1277*cdf0e10cSrcweir 			nAction = ACTION_STOP_TEXT_EDIT;
1278*cdf0e10cSrcweir 		}
1279*cdf0e10cSrcweir 		else if( mbCellSelectionMode )
1280*cdf0e10cSrcweir 		{
1281*cdf0e10cSrcweir 			// f2 with selected cells removes selection
1282*cdf0e10cSrcweir 			nAction = ACTION_REMOVE_SELECTION;
1283*cdf0e10cSrcweir 		}
1284*cdf0e10cSrcweir 		else
1285*cdf0e10cSrcweir 		{
1286*cdf0e10cSrcweir 			// f2 with no selection and no text edit starts text edit
1287*cdf0e10cSrcweir 			setSelectionStart( pTableObj->getFirstCell() );
1288*cdf0e10cSrcweir 			nAction = ACTION_EDIT_CELL;
1289*cdf0e10cSrcweir 		}
1290*cdf0e10cSrcweir 		break;
1291*cdf0e10cSrcweir 	}
1292*cdf0e10cSrcweir 	case awt::Key::HOME:
1293*cdf0e10cSrcweir 	case awt::Key::NUM7:
1294*cdf0e10cSrcweir 	{
1295*cdf0e10cSrcweir 		if( (bMod1 ||  bMod2) && (bTextEdit || mbCellSelectionMode) )
1296*cdf0e10cSrcweir 		{
1297*cdf0e10cSrcweir 			if( bMod1 && !bMod2 )
1298*cdf0e10cSrcweir 			{
1299*cdf0e10cSrcweir 				// strg + home jumps to first cell
1300*cdf0e10cSrcweir 				nAction = ACTION_GOTO_FIRST_CELL;
1301*cdf0e10cSrcweir 			}
1302*cdf0e10cSrcweir 			else if( !bMod1 && bMod2 )
1303*cdf0e10cSrcweir 			{
1304*cdf0e10cSrcweir 				// alt + home jumps to first column
1305*cdf0e10cSrcweir 				nAction = ACTION_GOTO_FIRST_COLUMN;
1306*cdf0e10cSrcweir 			}
1307*cdf0e10cSrcweir 		}
1308*cdf0e10cSrcweir 		break;
1309*cdf0e10cSrcweir 	}
1310*cdf0e10cSrcweir 	case awt::Key::END:
1311*cdf0e10cSrcweir 	case awt::Key::NUM1:
1312*cdf0e10cSrcweir 	{
1313*cdf0e10cSrcweir 		if( (bMod1 ||  bMod2) && (bTextEdit || mbCellSelectionMode) )
1314*cdf0e10cSrcweir 		{
1315*cdf0e10cSrcweir 			if( bMod1 && !bMod2 )
1316*cdf0e10cSrcweir 			{
1317*cdf0e10cSrcweir 				// strg + end jumps to last cell
1318*cdf0e10cSrcweir 				nAction = ACTION_GOTO_LAST_CELL;
1319*cdf0e10cSrcweir 			}
1320*cdf0e10cSrcweir 			else if( !bMod1 && bMod2 )
1321*cdf0e10cSrcweir 			{
1322*cdf0e10cSrcweir 				// alt + home jumps to last column
1323*cdf0e10cSrcweir 				nAction = ACTION_GOTO_LAST_COLUMN;
1324*cdf0e10cSrcweir 			}
1325*cdf0e10cSrcweir 		}
1326*cdf0e10cSrcweir 		break;
1327*cdf0e10cSrcweir 	}
1328*cdf0e10cSrcweir 
1329*cdf0e10cSrcweir 	case awt::Key::TAB:
1330*cdf0e10cSrcweir 	{
1331*cdf0e10cSrcweir 		if( bTextEdit || mbCellSelectionMode )
1332*cdf0e10cSrcweir 			nAction = ACTION_TAB;
1333*cdf0e10cSrcweir 		break;
1334*cdf0e10cSrcweir 	}
1335*cdf0e10cSrcweir 
1336*cdf0e10cSrcweir 	case awt::Key::UP:
1337*cdf0e10cSrcweir 	case awt::Key::NUM8:
1338*cdf0e10cSrcweir 	case awt::Key::DOWN:
1339*cdf0e10cSrcweir 	case awt::Key::NUM2:
1340*cdf0e10cSrcweir 	case awt::Key::LEFT:
1341*cdf0e10cSrcweir 	case awt::Key::NUM4:
1342*cdf0e10cSrcweir 	case awt::Key::RIGHT:
1343*cdf0e10cSrcweir 	case awt::Key::NUM6:
1344*cdf0e10cSrcweir 	{
1345*cdf0e10cSrcweir 		bool bTextMove = false;
1346*cdf0e10cSrcweir 
1347*cdf0e10cSrcweir 		if( !bMod1 && bMod2 )
1348*cdf0e10cSrcweir 		{
1349*cdf0e10cSrcweir 			if( (nCode == awt::Key::UP) || (nCode == awt::Key::NUM8) )
1350*cdf0e10cSrcweir 			{
1351*cdf0e10cSrcweir 				nAction = ACTION_GOTO_LEFT_CELL;
1352*cdf0e10cSrcweir 			}
1353*cdf0e10cSrcweir 			else if( (nCode == awt::Key::DOWN) || (nCode == awt::Key::NUM2) )
1354*cdf0e10cSrcweir 			{
1355*cdf0e10cSrcweir 				nAction = ACTION_GOTO_RIGHT_CELL;
1356*cdf0e10cSrcweir 			}
1357*cdf0e10cSrcweir 			break;
1358*cdf0e10cSrcweir 		}
1359*cdf0e10cSrcweir 
1360*cdf0e10cSrcweir 		if( !bTextMove )
1361*cdf0e10cSrcweir 		{
1362*cdf0e10cSrcweir 			OutlinerView* pOLV = mpView->GetTextEditOutlinerView();
1363*cdf0e10cSrcweir 			if( pOLV )
1364*cdf0e10cSrcweir 			{
1365*cdf0e10cSrcweir 				RemoveSelection();
1366*cdf0e10cSrcweir 				// during text edit, check if we navigate out of the cell
1367*cdf0e10cSrcweir 				ESelection aOldSelection = pOLV->GetSelection();
1368*cdf0e10cSrcweir 				pOLV->PostKeyEvent(rKEvt);
1369*cdf0e10cSrcweir 				bTextMove = pOLV && ( aOldSelection.IsEqual(pOLV->GetSelection()) );
1370*cdf0e10cSrcweir 				if( !bTextMove )
1371*cdf0e10cSrcweir 				{
1372*cdf0e10cSrcweir 					nAction = ACTION_NONE;
1373*cdf0e10cSrcweir 				}
1374*cdf0e10cSrcweir 			}
1375*cdf0e10cSrcweir 		}
1376*cdf0e10cSrcweir 
1377*cdf0e10cSrcweir 		if( mbCellSelectionMode || bTextMove )
1378*cdf0e10cSrcweir 		{
1379*cdf0e10cSrcweir 			// no text edit, navigate in cells if selection active
1380*cdf0e10cSrcweir 			switch( nCode )
1381*cdf0e10cSrcweir 			{
1382*cdf0e10cSrcweir 			case awt::Key::LEFT:
1383*cdf0e10cSrcweir 			case awt::Key::NUM4:
1384*cdf0e10cSrcweir 				nAction = ACTION_GOTO_LEFT_CELL;
1385*cdf0e10cSrcweir 				break;
1386*cdf0e10cSrcweir 			case awt::Key::RIGHT:
1387*cdf0e10cSrcweir 			case awt::Key::NUM6:
1388*cdf0e10cSrcweir 				nAction = ACTION_GOTO_RIGHT_CELL;
1389*cdf0e10cSrcweir 				break;
1390*cdf0e10cSrcweir 			case awt::Key::DOWN:
1391*cdf0e10cSrcweir 			case awt::Key::NUM2:
1392*cdf0e10cSrcweir 				nAction = ACTION_GOTO_DOWN_CELL;
1393*cdf0e10cSrcweir 				break;
1394*cdf0e10cSrcweir 			case awt::Key::UP:
1395*cdf0e10cSrcweir 			case awt::Key::NUM8:
1396*cdf0e10cSrcweir 				nAction = ACTION_GOTO_UP_CELL;
1397*cdf0e10cSrcweir 				break;
1398*cdf0e10cSrcweir 			}
1399*cdf0e10cSrcweir 		}
1400*cdf0e10cSrcweir 		break;
1401*cdf0e10cSrcweir 	}
1402*cdf0e10cSrcweir 	case awt::Key::PAGEUP:
1403*cdf0e10cSrcweir 		if( bMod2 )
1404*cdf0e10cSrcweir 			nAction = ACTION_GOTO_FIRST_ROW;
1405*cdf0e10cSrcweir 		break;
1406*cdf0e10cSrcweir 
1407*cdf0e10cSrcweir 	case awt::Key::PAGEDOWN:
1408*cdf0e10cSrcweir 		if( bMod2 )
1409*cdf0e10cSrcweir 			nAction = ACTION_GOTO_LAST_ROW;
1410*cdf0e10cSrcweir 		break;
1411*cdf0e10cSrcweir 	}
1412*cdf0e10cSrcweir 	return nAction;
1413*cdf0e10cSrcweir }
1414*cdf0e10cSrcweir 
1415*cdf0e10cSrcweir bool SvxTableController::executeAction( sal_uInt16 nAction, bool bSelect, Window* pWindow )
1416*cdf0e10cSrcweir {
1417*cdf0e10cSrcweir 	::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
1418*cdf0e10cSrcweir 	if( !pTableObj )
1419*cdf0e10cSrcweir 		return false;
1420*cdf0e10cSrcweir 
1421*cdf0e10cSrcweir 	switch( nAction )
1422*cdf0e10cSrcweir 	{
1423*cdf0e10cSrcweir 	case ACTION_GOTO_FIRST_CELL:
1424*cdf0e10cSrcweir 	{
1425*cdf0e10cSrcweir 		gotoCell( pTableObj->getFirstCell(), bSelect, pWindow, nAction );
1426*cdf0e10cSrcweir 		break;
1427*cdf0e10cSrcweir 	}
1428*cdf0e10cSrcweir 
1429*cdf0e10cSrcweir 	case ACTION_GOTO_LEFT_CELL:
1430*cdf0e10cSrcweir 	{
1431*cdf0e10cSrcweir 		gotoCell( pTableObj->getLeftCell( getSelectionEnd(), !bSelect ), bSelect, pWindow, nAction );
1432*cdf0e10cSrcweir 		break;
1433*cdf0e10cSrcweir 	}
1434*cdf0e10cSrcweir 
1435*cdf0e10cSrcweir 	case ACTION_GOTO_RIGHT_CELL:
1436*cdf0e10cSrcweir 	{
1437*cdf0e10cSrcweir 		gotoCell( pTableObj->getRightCell( getSelectionEnd(), !bSelect ), bSelect, pWindow, nAction);
1438*cdf0e10cSrcweir 		break;
1439*cdf0e10cSrcweir 	}
1440*cdf0e10cSrcweir 
1441*cdf0e10cSrcweir 	case ACTION_GOTO_LAST_CELL:
1442*cdf0e10cSrcweir 	{
1443*cdf0e10cSrcweir 		gotoCell( pTableObj->getLastCell(), bSelect, pWindow, nAction );
1444*cdf0e10cSrcweir 		break;
1445*cdf0e10cSrcweir 	}
1446*cdf0e10cSrcweir 
1447*cdf0e10cSrcweir 	case ACTION_GOTO_FIRST_COLUMN:
1448*cdf0e10cSrcweir 	{
1449*cdf0e10cSrcweir 		CellPos aPos( pTableObj->getFirstCell().mnCol, getSelectionEnd().mnRow );
1450*cdf0e10cSrcweir 		gotoCell( aPos, bSelect, pWindow, nAction );
1451*cdf0e10cSrcweir 		break;
1452*cdf0e10cSrcweir 	}
1453*cdf0e10cSrcweir 
1454*cdf0e10cSrcweir 	case ACTION_GOTO_LAST_COLUMN:
1455*cdf0e10cSrcweir 	{
1456*cdf0e10cSrcweir 		CellPos aPos( pTableObj->getLastCell().mnCol, getSelectionEnd().mnRow );
1457*cdf0e10cSrcweir 		gotoCell( aPos, bSelect, pWindow, nAction );
1458*cdf0e10cSrcweir 		break;
1459*cdf0e10cSrcweir 	}
1460*cdf0e10cSrcweir 
1461*cdf0e10cSrcweir 	case ACTION_GOTO_FIRST_ROW:
1462*cdf0e10cSrcweir 	{
1463*cdf0e10cSrcweir 		CellPos aPos( getSelectionEnd().mnCol, pTableObj->getFirstCell().mnRow );
1464*cdf0e10cSrcweir 		gotoCell( aPos, bSelect, pWindow, nAction );
1465*cdf0e10cSrcweir 		break;
1466*cdf0e10cSrcweir 	}
1467*cdf0e10cSrcweir 
1468*cdf0e10cSrcweir 	case ACTION_GOTO_UP_CELL:
1469*cdf0e10cSrcweir 	{
1470*cdf0e10cSrcweir 		gotoCell( pTableObj->getUpCell(getSelectionEnd(), !bSelect), bSelect, pWindow, nAction );
1471*cdf0e10cSrcweir 		break;
1472*cdf0e10cSrcweir 	}
1473*cdf0e10cSrcweir 
1474*cdf0e10cSrcweir 	case ACTION_GOTO_DOWN_CELL:
1475*cdf0e10cSrcweir 	{
1476*cdf0e10cSrcweir 		gotoCell( pTableObj->getDownCell(getSelectionEnd(), !bSelect), bSelect, pWindow, nAction );
1477*cdf0e10cSrcweir 		break;
1478*cdf0e10cSrcweir 	}
1479*cdf0e10cSrcweir 
1480*cdf0e10cSrcweir 	case ACTION_GOTO_LAST_ROW:
1481*cdf0e10cSrcweir 	{
1482*cdf0e10cSrcweir 		CellPos aPos( getSelectionEnd().mnCol, pTableObj->getLastCell().mnRow );
1483*cdf0e10cSrcweir 		gotoCell( aPos, bSelect, pWindow, nAction );
1484*cdf0e10cSrcweir 		break;
1485*cdf0e10cSrcweir 	}
1486*cdf0e10cSrcweir 
1487*cdf0e10cSrcweir 	case ACTION_EDIT_CELL:
1488*cdf0e10cSrcweir 		EditCell( getSelectionStart(), pWindow, 0, nAction );
1489*cdf0e10cSrcweir 		break;
1490*cdf0e10cSrcweir 
1491*cdf0e10cSrcweir 	case ACTION_STOP_TEXT_EDIT:
1492*cdf0e10cSrcweir 		StopTextEdit();
1493*cdf0e10cSrcweir 		break;
1494*cdf0e10cSrcweir 
1495*cdf0e10cSrcweir 	case ACTION_REMOVE_SELECTION:
1496*cdf0e10cSrcweir 		RemoveSelection();
1497*cdf0e10cSrcweir 		break;
1498*cdf0e10cSrcweir 
1499*cdf0e10cSrcweir 	case ACTION_START_SELECTION:
1500*cdf0e10cSrcweir 		StartSelection( getSelectionStart() );
1501*cdf0e10cSrcweir 		break;
1502*cdf0e10cSrcweir 
1503*cdf0e10cSrcweir 	case ACTION_TAB:
1504*cdf0e10cSrcweir 	{
1505*cdf0e10cSrcweir 		if( bSelect )
1506*cdf0e10cSrcweir 			gotoCell( pTableObj->getPreviousCell( getSelectionEnd(), true ), false, pWindow, nAction );
1507*cdf0e10cSrcweir 		else
1508*cdf0e10cSrcweir         {
1509*cdf0e10cSrcweir             CellPos aSelectionEnd( getSelectionEnd() );
1510*cdf0e10cSrcweir             CellPos aNextCell( pTableObj->getNextCell( aSelectionEnd, true ) );
1511*cdf0e10cSrcweir             if( aSelectionEnd == aNextCell )
1512*cdf0e10cSrcweir             {
1513*cdf0e10cSrcweir                 onInsert( SID_TABLE_INSERT_ROW, 0 );
1514*cdf0e10cSrcweir                 aNextCell = pTableObj->getNextCell( aSelectionEnd, true );
1515*cdf0e10cSrcweir             }
1516*cdf0e10cSrcweir 			gotoCell( aNextCell, false, pWindow, nAction );
1517*cdf0e10cSrcweir         }
1518*cdf0e10cSrcweir 		break;
1519*cdf0e10cSrcweir 	}
1520*cdf0e10cSrcweir 	}
1521*cdf0e10cSrcweir 
1522*cdf0e10cSrcweir 	return nAction != ACTION_HANDLED_BY_VIEW;
1523*cdf0e10cSrcweir }
1524*cdf0e10cSrcweir 
1525*cdf0e10cSrcweir // --------------------------------------------------------------------
1526*cdf0e10cSrcweir 
1527*cdf0e10cSrcweir void SvxTableController::gotoCell( const CellPos& rPos, bool bSelect, Window* pWindow, sal_uInt16 nAction )
1528*cdf0e10cSrcweir {
1529*cdf0e10cSrcweir 	if( mxTableObj.is() && static_cast<SdrTableObj*>(mxTableObj.get())->IsTextEditActive() )
1530*cdf0e10cSrcweir 		mpView->SdrEndTextEdit(sal_True);
1531*cdf0e10cSrcweir 
1532*cdf0e10cSrcweir 	if( bSelect )
1533*cdf0e10cSrcweir 	{
1534*cdf0e10cSrcweir 		maCursorLastPos = rPos;
1535*cdf0e10cSrcweir 		if( mxTableObj.is() )
1536*cdf0e10cSrcweir 			static_cast< SdrTableObj* >( mxTableObj.get() )->setActiveCell( rPos );
1537*cdf0e10cSrcweir 
1538*cdf0e10cSrcweir 		if( !mbCellSelectionMode )
1539*cdf0e10cSrcweir 		{
1540*cdf0e10cSrcweir 			setSelectedCells( maCursorFirstPos, rPos );
1541*cdf0e10cSrcweir 		}
1542*cdf0e10cSrcweir 		else
1543*cdf0e10cSrcweir 		{
1544*cdf0e10cSrcweir 			UpdateSelection( rPos );
1545*cdf0e10cSrcweir 		}
1546*cdf0e10cSrcweir 	}
1547*cdf0e10cSrcweir 	else
1548*cdf0e10cSrcweir 	{
1549*cdf0e10cSrcweir 		RemoveSelection();
1550*cdf0e10cSrcweir 		EditCell( rPos, pWindow, 0, nAction );
1551*cdf0e10cSrcweir 	}
1552*cdf0e10cSrcweir }
1553*cdf0e10cSrcweir 
1554*cdf0e10cSrcweir // --------------------------------------------------------------------
1555*cdf0e10cSrcweir 
1556*cdf0e10cSrcweir const CellPos& SvxTableController::getSelectionStart()
1557*cdf0e10cSrcweir {
1558*cdf0e10cSrcweir 	checkCell( maCursorFirstPos );
1559*cdf0e10cSrcweir 	return maCursorFirstPos;
1560*cdf0e10cSrcweir }
1561*cdf0e10cSrcweir 
1562*cdf0e10cSrcweir // --------------------------------------------------------------------
1563*cdf0e10cSrcweir 
1564*cdf0e10cSrcweir void SvxTableController::setSelectionStart( const CellPos& rPos )
1565*cdf0e10cSrcweir {
1566*cdf0e10cSrcweir 	maCursorFirstPos = rPos;
1567*cdf0e10cSrcweir }
1568*cdf0e10cSrcweir 
1569*cdf0e10cSrcweir // --------------------------------------------------------------------
1570*cdf0e10cSrcweir 
1571*cdf0e10cSrcweir const CellPos& SvxTableController::getSelectionEnd()
1572*cdf0e10cSrcweir {
1573*cdf0e10cSrcweir 	checkCell( maCursorLastPos );
1574*cdf0e10cSrcweir 	return maCursorLastPos;
1575*cdf0e10cSrcweir }
1576*cdf0e10cSrcweir 
1577*cdf0e10cSrcweir // --------------------------------------------------------------------
1578*cdf0e10cSrcweir 
1579*cdf0e10cSrcweir Reference< XCellCursor > SvxTableController::getSelectionCursor()
1580*cdf0e10cSrcweir {
1581*cdf0e10cSrcweir 	Reference< XCellCursor > xCursor;
1582*cdf0e10cSrcweir 
1583*cdf0e10cSrcweir 	if( mxTable.is() )
1584*cdf0e10cSrcweir 	{
1585*cdf0e10cSrcweir 		if( hasSelectedCells() )
1586*cdf0e10cSrcweir 		{
1587*cdf0e10cSrcweir 			CellPos aStart, aEnd;
1588*cdf0e10cSrcweir 			getSelectedCells( aStart, aEnd );
1589*cdf0e10cSrcweir 			xCursor = mxTable->createCursorByRange( mxTable->getCellRangeByPosition( aStart.mnCol, aStart.mnRow, aEnd.mnCol, aEnd.mnRow ) );
1590*cdf0e10cSrcweir 		}
1591*cdf0e10cSrcweir 		else
1592*cdf0e10cSrcweir 		{
1593*cdf0e10cSrcweir 			xCursor = mxTable->createCursor();
1594*cdf0e10cSrcweir 		}
1595*cdf0e10cSrcweir 	}
1596*cdf0e10cSrcweir 
1597*cdf0e10cSrcweir 	return xCursor;
1598*cdf0e10cSrcweir }
1599*cdf0e10cSrcweir 
1600*cdf0e10cSrcweir void SvxTableController::MergeRange( sal_Int32 nFirstCol, sal_Int32 nFirstRow, sal_Int32 nLastCol, sal_Int32 nLastRow )
1601*cdf0e10cSrcweir {
1602*cdf0e10cSrcweir 	if( mxTable.is() ) try
1603*cdf0e10cSrcweir 	{
1604*cdf0e10cSrcweir 		Reference< XMergeableCellRange > xRange( mxTable->createCursorByRange( mxTable->getCellRangeByPosition( nFirstCol, nFirstRow,nLastCol, nLastRow ) ), UNO_QUERY_THROW );
1605*cdf0e10cSrcweir 		if( xRange->isMergeable() )
1606*cdf0e10cSrcweir 		{
1607*cdf0e10cSrcweir 			const bool bUndo = mpModel && mpModel->IsUndoEnabled();
1608*cdf0e10cSrcweir 			if( bUndo )
1609*cdf0e10cSrcweir 			{
1610*cdf0e10cSrcweir 				mpModel->BegUndo( ImpGetResStr(STR_TABLE_MERGE) );
1611*cdf0e10cSrcweir 				mpModel->AddUndo( mpModel->GetSdrUndoFactory().CreateUndoGeoObject(*mxTableObj.get()) );
1612*cdf0e10cSrcweir 			}
1613*cdf0e10cSrcweir 
1614*cdf0e10cSrcweir 			xRange->merge();
1615*cdf0e10cSrcweir 
1616*cdf0e10cSrcweir 			if( bUndo )
1617*cdf0e10cSrcweir 				mpModel->EndUndo();
1618*cdf0e10cSrcweir 		}
1619*cdf0e10cSrcweir 	}
1620*cdf0e10cSrcweir 	catch( Exception& )
1621*cdf0e10cSrcweir 	{
1622*cdf0e10cSrcweir 		DBG_ASSERT( false, "sdr::table::SvxTableController::MergeRange(), exception caught!" );
1623*cdf0e10cSrcweir 	}
1624*cdf0e10cSrcweir }
1625*cdf0e10cSrcweir 
1626*cdf0e10cSrcweir 
1627*cdf0e10cSrcweir 
1628*cdf0e10cSrcweir // --------------------------------------------------------------------
1629*cdf0e10cSrcweir 
1630*cdf0e10cSrcweir void SvxTableController::checkCell( CellPos& rPos )
1631*cdf0e10cSrcweir {
1632*cdf0e10cSrcweir 	if( mxTable.is() ) try
1633*cdf0e10cSrcweir 	{
1634*cdf0e10cSrcweir 		if( rPos.mnCol >= mxTable->getColumnCount() )
1635*cdf0e10cSrcweir 			rPos.mnCol = mxTable->getColumnCount()-1;
1636*cdf0e10cSrcweir 
1637*cdf0e10cSrcweir 		if( rPos.mnRow >= mxTable->getRowCount() )
1638*cdf0e10cSrcweir 			rPos.mnRow = mxTable->getRowCount()-1;
1639*cdf0e10cSrcweir 	}
1640*cdf0e10cSrcweir 	catch( Exception& e )
1641*cdf0e10cSrcweir 	{
1642*cdf0e10cSrcweir 		(void)e;
1643*cdf0e10cSrcweir 		DBG_ERROR("sdr::table::SvxTableController::checkCell(), exception caught!" );
1644*cdf0e10cSrcweir 	}
1645*cdf0e10cSrcweir }
1646*cdf0e10cSrcweir 
1647*cdf0e10cSrcweir // --------------------------------------------------------------------
1648*cdf0e10cSrcweir 
1649*cdf0e10cSrcweir void SvxTableController::findMergeOrigin( CellPos& rPos )
1650*cdf0e10cSrcweir {
1651*cdf0e10cSrcweir 	if( mxTable.is() ) try
1652*cdf0e10cSrcweir 	{
1653*cdf0e10cSrcweir 		Reference< XMergeableCell > xCell( mxTable->getCellByPosition( rPos.mnCol, rPos.mnRow ), UNO_QUERY_THROW );
1654*cdf0e10cSrcweir 		if( xCell.is() && xCell->isMerged() )
1655*cdf0e10cSrcweir 		{
1656*cdf0e10cSrcweir 			::findMergeOrigin( mxTable, rPos.mnCol, rPos.mnRow, rPos.mnCol, rPos.mnRow );
1657*cdf0e10cSrcweir 		}
1658*cdf0e10cSrcweir 	}
1659*cdf0e10cSrcweir 	catch( Exception& e )
1660*cdf0e10cSrcweir 	{
1661*cdf0e10cSrcweir 		(void)e;
1662*cdf0e10cSrcweir 		DBG_ERROR("sdr::table::SvxTableController::findMergeOrigin(), exception caught!" );
1663*cdf0e10cSrcweir 	}
1664*cdf0e10cSrcweir }
1665*cdf0e10cSrcweir 
1666*cdf0e10cSrcweir // --------------------------------------------------------------------
1667*cdf0e10cSrcweir 
1668*cdf0e10cSrcweir void SvxTableController::EditCell( const CellPos& rPos, ::Window* pWindow, const awt::MouseEvent* pMouseEvent /*= 0*/, sal_uInt16 nAction /*= ACTION_NONE */ )
1669*cdf0e10cSrcweir {
1670*cdf0e10cSrcweir 	SdrPageView* pPV = mpView->GetSdrPageView();
1671*cdf0e10cSrcweir 
1672*cdf0e10cSrcweir 	::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
1673*cdf0e10cSrcweir 	if( pTableObj && pTableObj->GetPage() == pPV->GetPage() )
1674*cdf0e10cSrcweir 	{
1675*cdf0e10cSrcweir 		bool bEmptyOutliner = false;
1676*cdf0e10cSrcweir 
1677*cdf0e10cSrcweir 		if(!pTableObj->GetOutlinerParaObject() && mpView->GetTextEditOutliner())
1678*cdf0e10cSrcweir 		{
1679*cdf0e10cSrcweir 			::Outliner* pOutl = mpView->GetTextEditOutliner();
1680*cdf0e10cSrcweir 			sal_uIntPtr nParaAnz = pOutl->GetParagraphCount();
1681*cdf0e10cSrcweir 			Paragraph* p1stPara = pOutl->GetParagraph( 0 );
1682*cdf0e10cSrcweir 
1683*cdf0e10cSrcweir 			if(nParaAnz==1 && p1stPara)
1684*cdf0e10cSrcweir 			{
1685*cdf0e10cSrcweir 				// Bei nur einem Pararaph
1686*cdf0e10cSrcweir 				if (pOutl->GetText(p1stPara).Len() == 0)
1687*cdf0e10cSrcweir 				{
1688*cdf0e10cSrcweir 					bEmptyOutliner = true;
1689*cdf0e10cSrcweir 				}
1690*cdf0e10cSrcweir 			}
1691*cdf0e10cSrcweir 		}
1692*cdf0e10cSrcweir 
1693*cdf0e10cSrcweir 		CellPos aPos( rPos );
1694*cdf0e10cSrcweir 		findMergeOrigin( aPos );
1695*cdf0e10cSrcweir 
1696*cdf0e10cSrcweir 		if( pTableObj != mpView->GetTextEditObject() || bEmptyOutliner || !pTableObj->IsTextEditActive( aPos ) )
1697*cdf0e10cSrcweir 		{
1698*cdf0e10cSrcweir 			if( pTableObj->IsTextEditActive() )
1699*cdf0e10cSrcweir 				mpView->SdrEndTextEdit(sal_True);
1700*cdf0e10cSrcweir 
1701*cdf0e10cSrcweir 			pTableObj->setActiveCell( aPos );
1702*cdf0e10cSrcweir 
1703*cdf0e10cSrcweir 			// create new outliner, owner will be the SdrObjEditView
1704*cdf0e10cSrcweir 			SdrOutliner* pOutl = SdrMakeOutliner( OUTLINERMODE_OUTLINEOBJECT, mpModel );
1705*cdf0e10cSrcweir 			if( pTableObj->IsVerticalWriting() )
1706*cdf0e10cSrcweir 				pOutl->SetVertical( sal_True );
1707*cdf0e10cSrcweir 
1708*cdf0e10cSrcweir 			if(mpView->SdrBeginTextEdit(pTableObj, pPV, pWindow, sal_True, pOutl))
1709*cdf0e10cSrcweir 			{
1710*cdf0e10cSrcweir 				maCursorLastPos = maCursorFirstPos = rPos;
1711*cdf0e10cSrcweir 
1712*cdf0e10cSrcweir 				OutlinerView* pOLV = mpView->GetTextEditOutlinerView();
1713*cdf0e10cSrcweir 
1714*cdf0e10cSrcweir 				bool bNoSel = true;
1715*cdf0e10cSrcweir 
1716*cdf0e10cSrcweir 				if( pMouseEvent )
1717*cdf0e10cSrcweir 				{
1718*cdf0e10cSrcweir 					::MouseEvent aMEvt( *pMouseEvent );
1719*cdf0e10cSrcweir 
1720*cdf0e10cSrcweir 					SdrViewEvent aVEvt;
1721*cdf0e10cSrcweir 					SdrHitKind eHit = mpView->PickAnything(aMEvt, SDRMOUSEBUTTONDOWN, aVEvt);
1722*cdf0e10cSrcweir 
1723*cdf0e10cSrcweir 					if (eHit == SDRHIT_TEXTEDIT)
1724*cdf0e10cSrcweir 					{
1725*cdf0e10cSrcweir 						// Text getroffen
1726*cdf0e10cSrcweir 						pOLV->MouseButtonDown(aMEvt);
1727*cdf0e10cSrcweir 						pOLV->MouseMove(aMEvt);
1728*cdf0e10cSrcweir 						pOLV->MouseButtonUp(aMEvt);
1729*cdf0e10cSrcweir //						pOLV->MouseButtonDown(aMEvt);
1730*cdf0e10cSrcweir 						bNoSel = false;
1731*cdf0e10cSrcweir 					}
1732*cdf0e10cSrcweir 					else
1733*cdf0e10cSrcweir 					{
1734*cdf0e10cSrcweir 						nAction = ACTION_GOTO_LEFT_CELL;
1735*cdf0e10cSrcweir 					}
1736*cdf0e10cSrcweir 				}
1737*cdf0e10cSrcweir 
1738*cdf0e10cSrcweir 				if( bNoSel )
1739*cdf0e10cSrcweir 				{
1740*cdf0e10cSrcweir 					// Move cursor to end of text
1741*cdf0e10cSrcweir 					ESelection aNewSelection;
1742*cdf0e10cSrcweir 
1743*cdf0e10cSrcweir 					const WritingMode eMode = pTableObj->GetWritingMode();
1744*cdf0e10cSrcweir 					if( ((nAction == ACTION_GOTO_LEFT_CELL) || (nAction == ACTION_GOTO_RIGHT_CELL)) && (eMode != WritingMode_TB_RL) )
1745*cdf0e10cSrcweir 					{
1746*cdf0e10cSrcweir 						const bool bLast = ((nAction == ACTION_GOTO_LEFT_CELL) && (eMode == WritingMode_LR_TB)) ||
1747*cdf0e10cSrcweir 											 ((nAction == ACTION_GOTO_RIGHT_CELL) && (eMode == WritingMode_RL_TB));
1748*cdf0e10cSrcweir 
1749*cdf0e10cSrcweir 						if( bLast )
1750*cdf0e10cSrcweir 							aNewSelection = ESelection(EE_PARA_NOT_FOUND, EE_INDEX_NOT_FOUND, EE_PARA_NOT_FOUND, EE_INDEX_NOT_FOUND);
1751*cdf0e10cSrcweir 					}
1752*cdf0e10cSrcweir 					pOLV->SetSelection(aNewSelection);
1753*cdf0e10cSrcweir 				}
1754*cdf0e10cSrcweir 			}
1755*cdf0e10cSrcweir 		}
1756*cdf0e10cSrcweir 	}
1757*cdf0e10cSrcweir }
1758*cdf0e10cSrcweir 
1759*cdf0e10cSrcweir // --------------------------------------------------------------------
1760*cdf0e10cSrcweir 
1761*cdf0e10cSrcweir bool SvxTableController::StopTextEdit()
1762*cdf0e10cSrcweir {
1763*cdf0e10cSrcweir 	if(mpView->IsTextEdit())
1764*cdf0e10cSrcweir 	{
1765*cdf0e10cSrcweir 		mpView->SdrEndTextEdit();
1766*cdf0e10cSrcweir 		mpView->SetCurrentObj(OBJ_TABLE);
1767*cdf0e10cSrcweir 		mpView->SetEditMode(SDREDITMODE_EDIT);
1768*cdf0e10cSrcweir 		return true;
1769*cdf0e10cSrcweir 	}
1770*cdf0e10cSrcweir 	else
1771*cdf0e10cSrcweir 	{
1772*cdf0e10cSrcweir 		return false;
1773*cdf0e10cSrcweir 	}
1774*cdf0e10cSrcweir }
1775*cdf0e10cSrcweir 
1776*cdf0e10cSrcweir // --------------------------------------------------------------------
1777*cdf0e10cSrcweir 
1778*cdf0e10cSrcweir void SvxTableController::DeleteTable()
1779*cdf0e10cSrcweir {
1780*cdf0e10cSrcweir 	//
1781*cdf0e10cSrcweir }
1782*cdf0e10cSrcweir 
1783*cdf0e10cSrcweir // --------------------------------------------------------------------
1784*cdf0e10cSrcweir 
1785*cdf0e10cSrcweir void SvxTableController::getSelectedCells( CellPos& rFirst, CellPos& rLast )
1786*cdf0e10cSrcweir {
1787*cdf0e10cSrcweir 	if( mbCellSelectionMode )
1788*cdf0e10cSrcweir 	{
1789*cdf0e10cSrcweir 		checkCell( maCursorFirstPos );
1790*cdf0e10cSrcweir 		checkCell( maCursorLastPos );
1791*cdf0e10cSrcweir 
1792*cdf0e10cSrcweir 		rFirst.mnCol = std::min( maCursorFirstPos.mnCol, maCursorLastPos.mnCol );
1793*cdf0e10cSrcweir 		rFirst.mnRow = std::min( maCursorFirstPos.mnRow, maCursorLastPos.mnRow );
1794*cdf0e10cSrcweir 		rLast.mnCol = std::max( maCursorFirstPos.mnCol, maCursorLastPos.mnCol );
1795*cdf0e10cSrcweir 		rLast.mnRow = std::max( maCursorFirstPos.mnRow, maCursorLastPos.mnRow );
1796*cdf0e10cSrcweir 
1797*cdf0e10cSrcweir 		bool bExt = false;
1798*cdf0e10cSrcweir 		if( mxTable.is() ) do
1799*cdf0e10cSrcweir 		{
1800*cdf0e10cSrcweir 			bExt = false;
1801*cdf0e10cSrcweir 			for( sal_Int32 nRow = rFirst.mnRow; nRow <= rLast.mnRow && !bExt; nRow++ )
1802*cdf0e10cSrcweir 			{
1803*cdf0e10cSrcweir 				for( sal_Int32 nCol = rFirst.mnCol; nCol <= rLast.mnCol && !bExt; nCol++ )
1804*cdf0e10cSrcweir 				{
1805*cdf0e10cSrcweir 					Reference< XMergeableCell > xCell( mxTable->getCellByPosition( nCol, nRow ), UNO_QUERY );
1806*cdf0e10cSrcweir 					if( !xCell.is() )
1807*cdf0e10cSrcweir 						continue;
1808*cdf0e10cSrcweir 
1809*cdf0e10cSrcweir 					if( xCell->isMerged() )
1810*cdf0e10cSrcweir 					{
1811*cdf0e10cSrcweir 						CellPos aPos( nCol, nRow );
1812*cdf0e10cSrcweir 						findMergeOrigin( aPos );
1813*cdf0e10cSrcweir 						if( (aPos.mnCol < rFirst.mnCol) || (aPos.mnRow < rFirst.mnRow) )
1814*cdf0e10cSrcweir 						{
1815*cdf0e10cSrcweir 							rFirst.mnCol = std::min( rFirst.mnCol, aPos.mnCol );
1816*cdf0e10cSrcweir 							rFirst.mnRow = std::min( rFirst.mnRow, aPos.mnRow );
1817*cdf0e10cSrcweir 							bExt = true;
1818*cdf0e10cSrcweir 						}
1819*cdf0e10cSrcweir 					}
1820*cdf0e10cSrcweir 					else
1821*cdf0e10cSrcweir 					{
1822*cdf0e10cSrcweir 						if( ((nCol + xCell->getColumnSpan() - 1) > rLast.mnCol) || (nRow + xCell->getRowSpan() - 1 ) > rLast.mnRow )
1823*cdf0e10cSrcweir 						{
1824*cdf0e10cSrcweir 							rLast.mnCol = std::max( rLast.mnCol, nCol + xCell->getColumnSpan() - 1 );
1825*cdf0e10cSrcweir 							rLast.mnRow = std::max( rLast.mnRow, nRow + xCell->getRowSpan() - 1 );
1826*cdf0e10cSrcweir 							bExt = true;
1827*cdf0e10cSrcweir 						}
1828*cdf0e10cSrcweir 					}
1829*cdf0e10cSrcweir 				}
1830*cdf0e10cSrcweir 			}
1831*cdf0e10cSrcweir 		}
1832*cdf0e10cSrcweir 		while(bExt);
1833*cdf0e10cSrcweir 	}
1834*cdf0e10cSrcweir 	else if( mpView && mpView->IsTextEdit() )
1835*cdf0e10cSrcweir 	{
1836*cdf0e10cSrcweir 		rFirst = getSelectionStart();
1837*cdf0e10cSrcweir 		findMergeOrigin( rFirst );
1838*cdf0e10cSrcweir 		rLast = rFirst;
1839*cdf0e10cSrcweir 
1840*cdf0e10cSrcweir 		if( mxTable.is() )
1841*cdf0e10cSrcweir 		{
1842*cdf0e10cSrcweir 			Reference< XMergeableCell > xCell( mxTable->getCellByPosition( rLast.mnCol, rLast.mnRow ), UNO_QUERY );
1843*cdf0e10cSrcweir 			if( xCell.is() )
1844*cdf0e10cSrcweir 			{
1845*cdf0e10cSrcweir 				rLast.mnCol += xCell->getColumnSpan() - 1;
1846*cdf0e10cSrcweir 				rLast.mnRow += xCell->getRowSpan() - 1;
1847*cdf0e10cSrcweir 			}
1848*cdf0e10cSrcweir 		}
1849*cdf0e10cSrcweir 	}
1850*cdf0e10cSrcweir 	else
1851*cdf0e10cSrcweir 	{
1852*cdf0e10cSrcweir 		rFirst.mnCol = 0;
1853*cdf0e10cSrcweir 		rFirst.mnRow = 0;
1854*cdf0e10cSrcweir 		if( mxTable.is() )
1855*cdf0e10cSrcweir 		{
1856*cdf0e10cSrcweir 			rLast.mnRow = mxTable->getRowCount()-1;
1857*cdf0e10cSrcweir 			rLast.mnCol = mxTable->getColumnCount()-1;
1858*cdf0e10cSrcweir 		}
1859*cdf0e10cSrcweir 		else
1860*cdf0e10cSrcweir 		{
1861*cdf0e10cSrcweir 			rLast.mnRow = 0;
1862*cdf0e10cSrcweir 			rLast.mnCol = 0;
1863*cdf0e10cSrcweir 		}
1864*cdf0e10cSrcweir 	}
1865*cdf0e10cSrcweir }
1866*cdf0e10cSrcweir 
1867*cdf0e10cSrcweir // --------------------------------------------------------------------
1868*cdf0e10cSrcweir 
1869*cdf0e10cSrcweir void SvxTableController::StartSelection( const CellPos& rPos )
1870*cdf0e10cSrcweir {
1871*cdf0e10cSrcweir 	StopTextEdit();
1872*cdf0e10cSrcweir 	mbCellSelectionMode = true;
1873*cdf0e10cSrcweir 	maCursorLastPos = maCursorFirstPos = rPos;
1874*cdf0e10cSrcweir 	mpView->MarkListHasChanged();
1875*cdf0e10cSrcweir }
1876*cdf0e10cSrcweir 
1877*cdf0e10cSrcweir // --------------------------------------------------------------------
1878*cdf0e10cSrcweir 
1879*cdf0e10cSrcweir void SvxTableController::setSelectedCells( const CellPos& rStart, const CellPos& rEnd )
1880*cdf0e10cSrcweir {
1881*cdf0e10cSrcweir 	StopTextEdit();
1882*cdf0e10cSrcweir 	mbCellSelectionMode = true;
1883*cdf0e10cSrcweir 	maCursorFirstPos = rStart;
1884*cdf0e10cSrcweir 	UpdateSelection( rEnd );
1885*cdf0e10cSrcweir }
1886*cdf0e10cSrcweir 
1887*cdf0e10cSrcweir // --------------------------------------------------------------------
1888*cdf0e10cSrcweir 
1889*cdf0e10cSrcweir void SvxTableController::UpdateSelection( const CellPos& rPos )
1890*cdf0e10cSrcweir {
1891*cdf0e10cSrcweir 	maCursorLastPos = rPos;
1892*cdf0e10cSrcweir 	mpView->MarkListHasChanged();
1893*cdf0e10cSrcweir }
1894*cdf0e10cSrcweir 
1895*cdf0e10cSrcweir // --------------------------------------------------------------------
1896*cdf0e10cSrcweir 
1897*cdf0e10cSrcweir void SvxTableController::clearSelection()
1898*cdf0e10cSrcweir {
1899*cdf0e10cSrcweir 	RemoveSelection();
1900*cdf0e10cSrcweir }
1901*cdf0e10cSrcweir 
1902*cdf0e10cSrcweir // --------------------------------------------------------------------
1903*cdf0e10cSrcweir 
1904*cdf0e10cSrcweir void SvxTableController::selectAll()
1905*cdf0e10cSrcweir {
1906*cdf0e10cSrcweir 	if( mxTable.is() )
1907*cdf0e10cSrcweir 	{
1908*cdf0e10cSrcweir 		CellPos aPos1, aPos2( mxTable->getColumnCount()-1, mxTable->getRowCount()-1 );
1909*cdf0e10cSrcweir 		if( (aPos2.mnCol >= 0) && (aPos2.mnRow >= 0) )
1910*cdf0e10cSrcweir 		{
1911*cdf0e10cSrcweir 			setSelectedCells( aPos1, aPos2 );
1912*cdf0e10cSrcweir 		}
1913*cdf0e10cSrcweir 	}
1914*cdf0e10cSrcweir }
1915*cdf0e10cSrcweir 
1916*cdf0e10cSrcweir // --------------------------------------------------------------------
1917*cdf0e10cSrcweir 
1918*cdf0e10cSrcweir void SvxTableController::RemoveSelection()
1919*cdf0e10cSrcweir {
1920*cdf0e10cSrcweir 	if( mbCellSelectionMode )
1921*cdf0e10cSrcweir 	{
1922*cdf0e10cSrcweir 		mbCellSelectionMode = false;
1923*cdf0e10cSrcweir 		mpView->MarkListHasChanged();
1924*cdf0e10cSrcweir 	}
1925*cdf0e10cSrcweir }
1926*cdf0e10cSrcweir 
1927*cdf0e10cSrcweir // --------------------------------------------------------------------
1928*cdf0e10cSrcweir 
1929*cdf0e10cSrcweir void SvxTableController::onTableModified()
1930*cdf0e10cSrcweir {
1931*cdf0e10cSrcweir 	if( mnUpdateEvent == 0 )
1932*cdf0e10cSrcweir 		mnUpdateEvent = Application::PostUserEvent( LINK( this, SvxTableController, UpdateHdl ) );
1933*cdf0e10cSrcweir }
1934*cdf0e10cSrcweir // --------------------------------------------------------------------
1935*cdf0e10cSrcweir 
1936*cdf0e10cSrcweir void SvxTableController::updateSelectionOverlay()
1937*cdf0e10cSrcweir {
1938*cdf0e10cSrcweir 	destroySelectionOverlay();
1939*cdf0e10cSrcweir 	if( mbCellSelectionMode )
1940*cdf0e10cSrcweir 	{
1941*cdf0e10cSrcweir 		::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
1942*cdf0e10cSrcweir 		if( pTableObj )
1943*cdf0e10cSrcweir 		{
1944*cdf0e10cSrcweir 			sdr::overlay::OverlayObjectCell::RangeVector aRanges;
1945*cdf0e10cSrcweir 
1946*cdf0e10cSrcweir 			Rectangle aRect;
1947*cdf0e10cSrcweir 			CellPos aStart,aEnd;
1948*cdf0e10cSrcweir 			getSelectedCells( aStart, aEnd );
1949*cdf0e10cSrcweir 			pTableObj->getCellBounds( aStart, aRect );
1950*cdf0e10cSrcweir 
1951*cdf0e10cSrcweir 			basegfx::B2DRange a2DRange( basegfx::B2DPoint(aRect.Left(), aRect.Top()) );
1952*cdf0e10cSrcweir 			a2DRange.expand( basegfx::B2DPoint(aRect.Right(), aRect.Bottom()) );
1953*cdf0e10cSrcweir 
1954*cdf0e10cSrcweir 			findMergeOrigin( aEnd );
1955*cdf0e10cSrcweir 			pTableObj->getCellBounds( aEnd, aRect );
1956*cdf0e10cSrcweir 			a2DRange.expand( basegfx::B2DPoint(aRect.Left(), aRect.Top()) );
1957*cdf0e10cSrcweir 			a2DRange.expand( basegfx::B2DPoint(aRect.Right(), aRect.Bottom()) );
1958*cdf0e10cSrcweir 			aRanges.push_back( a2DRange );
1959*cdf0e10cSrcweir 
1960*cdf0e10cSrcweir 			::Color aHighlight( COL_BLUE );
1961*cdf0e10cSrcweir 			OutputDevice* pOutDev = mpView->GetFirstOutputDevice();
1962*cdf0e10cSrcweir 			if( pOutDev )
1963*cdf0e10cSrcweir 				aHighlight = pOutDev->GetSettings().GetStyleSettings().GetHighlightColor();
1964*cdf0e10cSrcweir 
1965*cdf0e10cSrcweir 			const sal_uInt32 nCount = mpView->PaintWindowCount();
1966*cdf0e10cSrcweir 			for( sal_uInt32 nIndex = 0; nIndex < nCount; nIndex++ )
1967*cdf0e10cSrcweir 			{
1968*cdf0e10cSrcweir 				SdrPaintWindow* pPaintWindow = mpView->GetPaintWindow(nIndex);
1969*cdf0e10cSrcweir 				if( pPaintWindow )
1970*cdf0e10cSrcweir 				{
1971*cdf0e10cSrcweir 					::sdr::overlay::OverlayManager* pOverlayManager = pPaintWindow->GetOverlayManager();
1972*cdf0e10cSrcweir 					if( pOverlayManager )
1973*cdf0e10cSrcweir 					{
1974*cdf0e10cSrcweir 						// sdr::overlay::CellOverlayType eType = sdr::overlay::CELL_OVERLAY_INVERT;
1975*cdf0e10cSrcweir 						sdr::overlay::CellOverlayType eType = sdr::overlay::CELL_OVERLAY_TRANSPARENT;
1976*cdf0e10cSrcweir 
1977*cdf0e10cSrcweir 						sdr::overlay::OverlayObjectCell* pOverlay = new sdr::overlay::OverlayObjectCell( eType, aHighlight, aRanges );
1978*cdf0e10cSrcweir 
1979*cdf0e10cSrcweir 						pOverlayManager->add(*pOverlay);
1980*cdf0e10cSrcweir 						mpSelectionOverlay = new ::sdr::overlay::OverlayObjectList;
1981*cdf0e10cSrcweir 						mpSelectionOverlay->append(*pOverlay);
1982*cdf0e10cSrcweir 					}
1983*cdf0e10cSrcweir 				}
1984*cdf0e10cSrcweir 			}
1985*cdf0e10cSrcweir 		}
1986*cdf0e10cSrcweir 	}
1987*cdf0e10cSrcweir }
1988*cdf0e10cSrcweir 
1989*cdf0e10cSrcweir // --------------------------------------------------------------------
1990*cdf0e10cSrcweir 
1991*cdf0e10cSrcweir void SvxTableController::destroySelectionOverlay()
1992*cdf0e10cSrcweir {
1993*cdf0e10cSrcweir 	if( mpSelectionOverlay )
1994*cdf0e10cSrcweir 	{
1995*cdf0e10cSrcweir 		delete mpSelectionOverlay;
1996*cdf0e10cSrcweir 		mpSelectionOverlay = 0;
1997*cdf0e10cSrcweir 	}
1998*cdf0e10cSrcweir }
1999*cdf0e10cSrcweir 
2000*cdf0e10cSrcweir // --------------------------------------------------------------------
2001*cdf0e10cSrcweir 
2002*cdf0e10cSrcweir void SvxTableController::MergeAttrFromSelectedCells(SfxItemSet& rAttr, bool bOnlyHardAttr) const
2003*cdf0e10cSrcweir {
2004*cdf0e10cSrcweir 	if( mxTable.is() )
2005*cdf0e10cSrcweir 	{
2006*cdf0e10cSrcweir 		CellPos aStart, aEnd;
2007*cdf0e10cSrcweir 		const_cast<SvxTableController&>(*this).getSelectedCells( aStart, aEnd );
2008*cdf0e10cSrcweir 
2009*cdf0e10cSrcweir 		for( sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++ )
2010*cdf0e10cSrcweir 		{
2011*cdf0e10cSrcweir 			for( sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++ )
2012*cdf0e10cSrcweir 			{
2013*cdf0e10cSrcweir 				CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
2014*cdf0e10cSrcweir 				if( xCell.is() && !xCell->isMerged() )
2015*cdf0e10cSrcweir 				{
2016*cdf0e10cSrcweir 					const SfxItemSet& rSet = xCell->GetItemSet();
2017*cdf0e10cSrcweir 					SfxWhichIter aIter(rSet);
2018*cdf0e10cSrcweir 					sal_uInt16 nWhich(aIter.FirstWhich());
2019*cdf0e10cSrcweir 					while(nWhich)
2020*cdf0e10cSrcweir 					{
2021*cdf0e10cSrcweir 						if(!bOnlyHardAttr)
2022*cdf0e10cSrcweir 						{
2023*cdf0e10cSrcweir 							if(SFX_ITEM_DONTCARE == rSet.GetItemState(nWhich, sal_False))
2024*cdf0e10cSrcweir 								rAttr.InvalidateItem(nWhich);
2025*cdf0e10cSrcweir 							else
2026*cdf0e10cSrcweir 								rAttr.MergeValue(rSet.Get(nWhich), sal_True);
2027*cdf0e10cSrcweir 						}
2028*cdf0e10cSrcweir 						else if(SFX_ITEM_SET == rSet.GetItemState(nWhich, sal_False))
2029*cdf0e10cSrcweir 						{
2030*cdf0e10cSrcweir 							const SfxPoolItem& rItem = rSet.Get(nWhich);
2031*cdf0e10cSrcweir 							rAttr.MergeValue(rItem, sal_True);
2032*cdf0e10cSrcweir 						}
2033*cdf0e10cSrcweir 
2034*cdf0e10cSrcweir 						nWhich = aIter.NextWhich();
2035*cdf0e10cSrcweir 					}
2036*cdf0e10cSrcweir 				}
2037*cdf0e10cSrcweir 			}
2038*cdf0e10cSrcweir 		}
2039*cdf0e10cSrcweir 	}
2040*cdf0e10cSrcweir 
2041*cdf0e10cSrcweir 	if( mpView->IsTextEdit() )
2042*cdf0e10cSrcweir 	{
2043*cdf0e10cSrcweir 	}
2044*cdf0e10cSrcweir }
2045*cdf0e10cSrcweir 
2046*cdf0e10cSrcweir // --------------------------------------------------------------------
2047*cdf0e10cSrcweir 
2048*cdf0e10cSrcweir const sal_uInt16 CELL_BEFORE = 0x0001;
2049*cdf0e10cSrcweir const sal_uInt16 CELL_LEFT   = 0x0002;
2050*cdf0e10cSrcweir const sal_uInt16 CELL_RIGHT  = 0x0004;
2051*cdf0e10cSrcweir const sal_uInt16 CELL_AFTER  = 0x0008;
2052*cdf0e10cSrcweir 
2053*cdf0e10cSrcweir const sal_uInt16 CELL_UPPER  = 0x0010;
2054*cdf0e10cSrcweir const sal_uInt16 CELL_TOP    = 0x0020;
2055*cdf0e10cSrcweir const sal_uInt16 CELL_BOTTOM = 0x0040;
2056*cdf0e10cSrcweir const sal_uInt16 CELL_LOWER  = 0x0080;
2057*cdf0e10cSrcweir 
2058*cdf0e10cSrcweir // --------------------------------------------------------------------
2059*cdf0e10cSrcweir 
2060*cdf0e10cSrcweir static void ImplSetLinePreserveColor( SvxBoxItem& rNewFrame, const SvxBorderLine* pNew, sal_uInt16 nLine )
2061*cdf0e10cSrcweir {
2062*cdf0e10cSrcweir 	if( pNew )
2063*cdf0e10cSrcweir 	{
2064*cdf0e10cSrcweir 		const SvxBorderLine* pOld = rNewFrame.GetLine(nLine);
2065*cdf0e10cSrcweir 		if( pOld )
2066*cdf0e10cSrcweir 		{
2067*cdf0e10cSrcweir 			SvxBorderLine aNewLine( *pNew );
2068*cdf0e10cSrcweir 			aNewLine.SetColor( pOld->GetColor() );
2069*cdf0e10cSrcweir 			rNewFrame.SetLine( &aNewLine, nLine );
2070*cdf0e10cSrcweir 			return;
2071*cdf0e10cSrcweir 		}
2072*cdf0e10cSrcweir 	}
2073*cdf0e10cSrcweir 	rNewFrame.SetLine( pNew, nLine );
2074*cdf0e10cSrcweir }
2075*cdf0e10cSrcweir 
2076*cdf0e10cSrcweir // --------------------------------------------------------------------
2077*cdf0e10cSrcweir 
2078*cdf0e10cSrcweir static void ImplApplyBoxItem( sal_uInt16 nCellFlags, const SvxBoxItem* pBoxItem, const SvxBoxInfoItem* pBoxInfoItem, SvxBoxItem& rNewFrame )
2079*cdf0e10cSrcweir {
2080*cdf0e10cSrcweir 	if( (nCellFlags & (CELL_BEFORE|CELL_AFTER|CELL_UPPER|CELL_LOWER)) != 0 )
2081*cdf0e10cSrcweir 	{
2082*cdf0e10cSrcweir 		// current cell is outside the selection
2083*cdf0e10cSrcweir 
2084*cdf0e10cSrcweir 		if( (nCellFlags & ( CELL_BEFORE|CELL_AFTER)) == 0 ) // check if its not nw or ne corner
2085*cdf0e10cSrcweir 		{
2086*cdf0e10cSrcweir 			if( nCellFlags & CELL_UPPER )
2087*cdf0e10cSrcweir 			{
2088*cdf0e10cSrcweir 				if( pBoxInfoItem->IsValid(VALID_TOP) )
2089*cdf0e10cSrcweir 					rNewFrame.SetLine(0, BOX_LINE_BOTTOM );
2090*cdf0e10cSrcweir 			}
2091*cdf0e10cSrcweir 			else if( nCellFlags & CELL_LOWER )
2092*cdf0e10cSrcweir 			{
2093*cdf0e10cSrcweir 				if( pBoxInfoItem->IsValid(VALID_BOTTOM) )
2094*cdf0e10cSrcweir 					rNewFrame.SetLine( 0, BOX_LINE_TOP );
2095*cdf0e10cSrcweir 			}
2096*cdf0e10cSrcweir 		}
2097*cdf0e10cSrcweir 		else if( (nCellFlags & ( CELL_UPPER|CELL_LOWER)) == 0 ) // check if its not sw or se corner
2098*cdf0e10cSrcweir 		{
2099*cdf0e10cSrcweir 			if( nCellFlags & CELL_BEFORE )
2100*cdf0e10cSrcweir 			{
2101*cdf0e10cSrcweir 				if( pBoxInfoItem->IsValid(VALID_LEFT) )
2102*cdf0e10cSrcweir 					rNewFrame.SetLine( 0, BOX_LINE_RIGHT );
2103*cdf0e10cSrcweir 			}
2104*cdf0e10cSrcweir 			else if( nCellFlags & CELL_AFTER )
2105*cdf0e10cSrcweir 			{
2106*cdf0e10cSrcweir 				if( pBoxInfoItem->IsValid(VALID_RIGHT) )
2107*cdf0e10cSrcweir 					rNewFrame.SetLine( 0, BOX_LINE_LEFT );
2108*cdf0e10cSrcweir 			}
2109*cdf0e10cSrcweir 		}
2110*cdf0e10cSrcweir 	}
2111*cdf0e10cSrcweir 	else
2112*cdf0e10cSrcweir 	{
2113*cdf0e10cSrcweir 		// current cell is inside the selection
2114*cdf0e10cSrcweir 
2115*cdf0e10cSrcweir 		if( (nCellFlags & CELL_LEFT) ? pBoxInfoItem->IsValid(VALID_LEFT) : pBoxInfoItem->IsValid(VALID_VERT) )
2116*cdf0e10cSrcweir 			rNewFrame.SetLine( (nCellFlags & CELL_LEFT) ? pBoxItem->GetLeft() : pBoxInfoItem->GetVert(), BOX_LINE_LEFT );
2117*cdf0e10cSrcweir 
2118*cdf0e10cSrcweir 		if( (nCellFlags & CELL_RIGHT) ? pBoxInfoItem->IsValid(VALID_RIGHT) : pBoxInfoItem->IsValid(VALID_VERT) )
2119*cdf0e10cSrcweir 			rNewFrame.SetLine( (nCellFlags & CELL_RIGHT) ? pBoxItem->GetRight() : pBoxInfoItem->GetVert(), BOX_LINE_RIGHT );
2120*cdf0e10cSrcweir 
2121*cdf0e10cSrcweir 		if( (nCellFlags & CELL_TOP) ? pBoxInfoItem->IsValid(VALID_TOP) : pBoxInfoItem->IsValid(VALID_HORI) )
2122*cdf0e10cSrcweir 			rNewFrame.SetLine( (nCellFlags & CELL_TOP) ? pBoxItem->GetTop() : pBoxInfoItem->GetHori(), BOX_LINE_TOP );
2123*cdf0e10cSrcweir 
2124*cdf0e10cSrcweir 		if( (nCellFlags & CELL_BOTTOM) ? pBoxInfoItem->IsValid(VALID_BOTTOM) : pBoxInfoItem->IsValid(VALID_HORI) )
2125*cdf0e10cSrcweir 			rNewFrame.SetLine( (nCellFlags & CELL_BOTTOM) ? pBoxItem->GetBottom() : pBoxInfoItem->GetHori(), BOX_LINE_BOTTOM );
2126*cdf0e10cSrcweir 
2127*cdf0e10cSrcweir 		// apply distance to borders
2128*cdf0e10cSrcweir 		if( pBoxInfoItem->IsValid( VALID_DISTANCE ) )
2129*cdf0e10cSrcweir 			for( sal_uInt16 nLine = 0; nLine < 4; ++nLine )
2130*cdf0e10cSrcweir 				rNewFrame.SetDistance( pBoxItem->GetDistance( nLine ), nLine );
2131*cdf0e10cSrcweir 	}
2132*cdf0e10cSrcweir }
2133*cdf0e10cSrcweir 
2134*cdf0e10cSrcweir // --------------------------------------------------------------------
2135*cdf0e10cSrcweir 
2136*cdf0e10cSrcweir static void ImplSetLineColor( SvxBoxItem& rNewFrame, sal_uInt16 nLine, const Color& rColor )
2137*cdf0e10cSrcweir {
2138*cdf0e10cSrcweir 	const SvxBorderLine* pSourceLine = rNewFrame.GetLine( nLine );
2139*cdf0e10cSrcweir 	if( pSourceLine )
2140*cdf0e10cSrcweir 	{
2141*cdf0e10cSrcweir 		SvxBorderLine aLine( *pSourceLine );
2142*cdf0e10cSrcweir 		aLine.SetColor( rColor );
2143*cdf0e10cSrcweir 		rNewFrame.SetLine( &aLine, nLine );
2144*cdf0e10cSrcweir 	}
2145*cdf0e10cSrcweir }
2146*cdf0e10cSrcweir 
2147*cdf0e10cSrcweir // --------------------------------------------------------------------
2148*cdf0e10cSrcweir 
2149*cdf0e10cSrcweir static void ImplApplyLineColorItem( sal_uInt16 nCellFlags, const SvxColorItem* pLineColorItem, SvxBoxItem& rNewFrame )
2150*cdf0e10cSrcweir {
2151*cdf0e10cSrcweir 	const Color aColor( pLineColorItem->GetValue() );
2152*cdf0e10cSrcweir 
2153*cdf0e10cSrcweir 	if( (nCellFlags & (CELL_LOWER|CELL_BEFORE|CELL_AFTER)) == 0 )
2154*cdf0e10cSrcweir 		ImplSetLineColor( rNewFrame, BOX_LINE_BOTTOM, aColor );
2155*cdf0e10cSrcweir 
2156*cdf0e10cSrcweir 	if( (nCellFlags & (CELL_UPPER|CELL_BEFORE|CELL_AFTER)) == 0 )
2157*cdf0e10cSrcweir 		ImplSetLineColor( rNewFrame, BOX_LINE_TOP, aColor );
2158*cdf0e10cSrcweir 
2159*cdf0e10cSrcweir 	if( (nCellFlags & (CELL_UPPER|CELL_LOWER|CELL_AFTER)) == 0 )
2160*cdf0e10cSrcweir 		ImplSetLineColor( rNewFrame, BOX_LINE_RIGHT, aColor );
2161*cdf0e10cSrcweir 
2162*cdf0e10cSrcweir 	if( (nCellFlags & (CELL_UPPER|CELL_LOWER|CELL_BEFORE)) == 0 )
2163*cdf0e10cSrcweir 		ImplSetLineColor( rNewFrame, BOX_LINE_LEFT, aColor );
2164*cdf0e10cSrcweir }
2165*cdf0e10cSrcweir 
2166*cdf0e10cSrcweir // --------------------------------------------------------------------
2167*cdf0e10cSrcweir 
2168*cdf0e10cSrcweir static void ImplApplyBorderLineItem( sal_uInt16 nCellFlags, const SvxBorderLine* pBorderLineItem, SvxBoxItem& rNewFrame )
2169*cdf0e10cSrcweir {
2170*cdf0e10cSrcweir 	if( (nCellFlags & ( CELL_BEFORE|CELL_AFTER|CELL_UPPER|CELL_LOWER)) != 0 )
2171*cdf0e10cSrcweir 	{
2172*cdf0e10cSrcweir 		if( (nCellFlags & ( CELL_BEFORE|CELL_AFTER)) == 0 ) // check if its not nw or ne corner
2173*cdf0e10cSrcweir 		{
2174*cdf0e10cSrcweir 			if( nCellFlags & CELL_UPPER )
2175*cdf0e10cSrcweir 			{
2176*cdf0e10cSrcweir 				if( rNewFrame.GetBottom() )
2177*cdf0e10cSrcweir 					ImplSetLinePreserveColor( rNewFrame, pBorderLineItem, BOX_LINE_BOTTOM );
2178*cdf0e10cSrcweir 			}
2179*cdf0e10cSrcweir 			else if( nCellFlags & CELL_LOWER )
2180*cdf0e10cSrcweir 			{
2181*cdf0e10cSrcweir 				if( rNewFrame.GetTop() )
2182*cdf0e10cSrcweir 					ImplSetLinePreserveColor( rNewFrame, pBorderLineItem, BOX_LINE_TOP );
2183*cdf0e10cSrcweir 			}
2184*cdf0e10cSrcweir 		}
2185*cdf0e10cSrcweir 		else if( (nCellFlags & ( CELL_UPPER|CELL_LOWER)) == 0 ) // check if its not sw or se corner
2186*cdf0e10cSrcweir 		{
2187*cdf0e10cSrcweir 			if( nCellFlags & CELL_BEFORE )
2188*cdf0e10cSrcweir 			{
2189*cdf0e10cSrcweir 				if( rNewFrame.GetRight() )
2190*cdf0e10cSrcweir 					ImplSetLinePreserveColor( rNewFrame, pBorderLineItem, BOX_LINE_RIGHT );
2191*cdf0e10cSrcweir 			}
2192*cdf0e10cSrcweir 			else if( nCellFlags & CELL_AFTER )
2193*cdf0e10cSrcweir 			{
2194*cdf0e10cSrcweir 				if( rNewFrame.GetLeft() )
2195*cdf0e10cSrcweir 					ImplSetLinePreserveColor( rNewFrame, pBorderLineItem, BOX_LINE_LEFT );
2196*cdf0e10cSrcweir 			}
2197*cdf0e10cSrcweir 		}
2198*cdf0e10cSrcweir 	}
2199*cdf0e10cSrcweir 	else
2200*cdf0e10cSrcweir 	{
2201*cdf0e10cSrcweir 		if( rNewFrame.GetBottom() )
2202*cdf0e10cSrcweir 			ImplSetLinePreserveColor( rNewFrame, pBorderLineItem, BOX_LINE_BOTTOM );
2203*cdf0e10cSrcweir 		if( rNewFrame.GetTop() )
2204*cdf0e10cSrcweir 			ImplSetLinePreserveColor( rNewFrame, pBorderLineItem, BOX_LINE_TOP );
2205*cdf0e10cSrcweir 		if( rNewFrame.GetRight() )
2206*cdf0e10cSrcweir 			ImplSetLinePreserveColor( rNewFrame, pBorderLineItem, BOX_LINE_RIGHT );
2207*cdf0e10cSrcweir 		if( rNewFrame.GetLeft() )
2208*cdf0e10cSrcweir 			ImplSetLinePreserveColor( rNewFrame, pBorderLineItem, BOX_LINE_LEFT );
2209*cdf0e10cSrcweir 	}
2210*cdf0e10cSrcweir }
2211*cdf0e10cSrcweir 
2212*cdf0e10cSrcweir // --------------------------------------------------------------------
2213*cdf0e10cSrcweir 
2214*cdf0e10cSrcweir void SvxTableController::ApplyBorderAttr( const SfxItemSet& rAttr )
2215*cdf0e10cSrcweir {
2216*cdf0e10cSrcweir 	if( mxTable.is() )
2217*cdf0e10cSrcweir 	{
2218*cdf0e10cSrcweir 		const sal_Int32 nRowCount = mxTable->getRowCount();
2219*cdf0e10cSrcweir 		const sal_Int32 nColCount = mxTable->getColumnCount();
2220*cdf0e10cSrcweir 		if( nRowCount && nColCount )
2221*cdf0e10cSrcweir 		{
2222*cdf0e10cSrcweir 			const SvxBoxItem* pBoxItem = 0;
2223*cdf0e10cSrcweir 			if(SFX_ITEM_SET == rAttr.GetItemState(SDRATTR_TABLE_BORDER, sal_False) )
2224*cdf0e10cSrcweir 				pBoxItem = dynamic_cast< const SvxBoxItem* >( &rAttr.Get( SDRATTR_TABLE_BORDER ) );
2225*cdf0e10cSrcweir 
2226*cdf0e10cSrcweir 			const SvxBoxInfoItem* pBoxInfoItem = 0;
2227*cdf0e10cSrcweir 			if(SFX_ITEM_SET == rAttr.GetItemState(SDRATTR_TABLE_BORDER_INNER, sal_False) )
2228*cdf0e10cSrcweir 				pBoxInfoItem = dynamic_cast< const SvxBoxInfoItem* >( &rAttr.Get( SDRATTR_TABLE_BORDER_INNER ) );
2229*cdf0e10cSrcweir 
2230*cdf0e10cSrcweir 			const SvxColorItem* pLineColorItem = 0;
2231*cdf0e10cSrcweir 			if(SFX_ITEM_SET == rAttr.GetItemState(SID_FRAME_LINECOLOR, sal_False) )
2232*cdf0e10cSrcweir 				pLineColorItem = dynamic_cast< const SvxColorItem* >( &rAttr.Get( SID_FRAME_LINECOLOR ) );
2233*cdf0e10cSrcweir 
2234*cdf0e10cSrcweir 			const SvxBorderLine* pBorderLineItem = 0;
2235*cdf0e10cSrcweir 			if(SFX_ITEM_SET == rAttr.GetItemState(SID_FRAME_LINESTYLE, sal_False) )
2236*cdf0e10cSrcweir 				pBorderLineItem = ((const SvxLineItem&)rAttr.Get( SID_FRAME_LINESTYLE )).GetLine();
2237*cdf0e10cSrcweir 
2238*cdf0e10cSrcweir 			if( pBoxInfoItem && !pBoxItem )
2239*cdf0e10cSrcweir 			{
2240*cdf0e10cSrcweir 				const static SvxBoxItem gaEmptyBoxItem( SDRATTR_TABLE_BORDER );
2241*cdf0e10cSrcweir 				pBoxItem = &gaEmptyBoxItem;
2242*cdf0e10cSrcweir 			}
2243*cdf0e10cSrcweir 			else if( pBoxItem && !pBoxInfoItem )
2244*cdf0e10cSrcweir 			{
2245*cdf0e10cSrcweir 				const static SvxBoxInfoItem gaEmptyBoxInfoItem( SDRATTR_TABLE_BORDER_INNER );
2246*cdf0e10cSrcweir 				pBoxInfoItem = &gaEmptyBoxInfoItem;
2247*cdf0e10cSrcweir 			}
2248*cdf0e10cSrcweir 
2249*cdf0e10cSrcweir 			CellPos aStart, aEnd;
2250*cdf0e10cSrcweir 			getSelectedCells( aStart, aEnd );
2251*cdf0e10cSrcweir 
2252*cdf0e10cSrcweir 			const sal_Int32 nLastRow = std::min( aEnd.mnRow + 2, nRowCount );
2253*cdf0e10cSrcweir 			const sal_Int32 nLastCol = std::min( aEnd.mnCol + 2, nColCount );
2254*cdf0e10cSrcweir 
2255*cdf0e10cSrcweir 			for( sal_Int32 nRow = std::max( aStart.mnRow - 1, (sal_Int32)0 ); nRow < nLastRow; nRow++ )
2256*cdf0e10cSrcweir 			{
2257*cdf0e10cSrcweir 				sal_uInt16 nRowFlags = 0;
2258*cdf0e10cSrcweir 				nRowFlags |= (nRow == aStart.mnRow) ? CELL_TOP : 0;
2259*cdf0e10cSrcweir 				nRowFlags |= (nRow == aEnd.mnRow)   ? CELL_BOTTOM : 0;
2260*cdf0e10cSrcweir 				nRowFlags |= (nRow < aStart.mnRow)  ? CELL_UPPER : 0;
2261*cdf0e10cSrcweir 				nRowFlags |= (nRow > aEnd.mnRow)    ? CELL_LOWER : 0;
2262*cdf0e10cSrcweir 
2263*cdf0e10cSrcweir 				for( sal_Int32 nCol = std::max( aStart.mnCol - 1, (sal_Int32)0 ); nCol < nLastCol; nCol++ )
2264*cdf0e10cSrcweir 				{
2265*cdf0e10cSrcweir 					CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
2266*cdf0e10cSrcweir 					if( !xCell.is() )
2267*cdf0e10cSrcweir 						continue;
2268*cdf0e10cSrcweir 
2269*cdf0e10cSrcweir 					const SfxItemSet& rSet = xCell->GetItemSet();
2270*cdf0e10cSrcweir 					const SvxBoxItem* pOldOuter = (const SvxBoxItem*)	  &rSet.Get( SDRATTR_TABLE_BORDER );
2271*cdf0e10cSrcweir 
2272*cdf0e10cSrcweir 					SvxBoxItem aNewFrame( *pOldOuter );
2273*cdf0e10cSrcweir 
2274*cdf0e10cSrcweir 					sal_uInt16 nCellFlags = nRowFlags;
2275*cdf0e10cSrcweir 					nCellFlags |= (nCol == aStart.mnCol) ? CELL_LEFT : 0;
2276*cdf0e10cSrcweir 					nCellFlags |= (nCol == aEnd.mnCol)   ? CELL_RIGHT : 0;
2277*cdf0e10cSrcweir 					nCellFlags |= (nCol < aStart.mnCol)  ? CELL_BEFORE : 0;
2278*cdf0e10cSrcweir 					nCellFlags |= (nCol > aEnd.mnCol)    ? CELL_AFTER : 0;
2279*cdf0e10cSrcweir 
2280*cdf0e10cSrcweir 					if( pBoxItem && pBoxInfoItem )
2281*cdf0e10cSrcweir 						ImplApplyBoxItem( nCellFlags, pBoxItem, pBoxInfoItem, aNewFrame );
2282*cdf0e10cSrcweir 
2283*cdf0e10cSrcweir 					if( pLineColorItem )
2284*cdf0e10cSrcweir 						ImplApplyLineColorItem( nCellFlags, pLineColorItem, aNewFrame );
2285*cdf0e10cSrcweir 
2286*cdf0e10cSrcweir 					if( pBorderLineItem )
2287*cdf0e10cSrcweir 						ImplApplyBorderLineItem( nCellFlags, pBorderLineItem, aNewFrame );
2288*cdf0e10cSrcweir 
2289*cdf0e10cSrcweir 					if (aNewFrame != *pOldOuter)
2290*cdf0e10cSrcweir 					{
2291*cdf0e10cSrcweir 						SfxItemSet aAttr(*rSet.GetPool(), rSet.GetRanges());
2292*cdf0e10cSrcweir 						aAttr.Put(aNewFrame);
2293*cdf0e10cSrcweir 						xCell->SetMergedItemSetAndBroadcast( aAttr, false );
2294*cdf0e10cSrcweir 					}
2295*cdf0e10cSrcweir 				}
2296*cdf0e10cSrcweir 			}
2297*cdf0e10cSrcweir 		}
2298*cdf0e10cSrcweir 	}
2299*cdf0e10cSrcweir }
2300*cdf0e10cSrcweir 
2301*cdf0e10cSrcweir // --------------------------------------------------------------------
2302*cdf0e10cSrcweir 
2303*cdf0e10cSrcweir void SvxTableController::UpdateTableShape()
2304*cdf0e10cSrcweir {
2305*cdf0e10cSrcweir 	SdrObject* pTableObj = mxTableObj.get();
2306*cdf0e10cSrcweir 	if( pTableObj )
2307*cdf0e10cSrcweir 	{
2308*cdf0e10cSrcweir 		pTableObj->ActionChanged();
2309*cdf0e10cSrcweir 		pTableObj->BroadcastObjectChange();
2310*cdf0e10cSrcweir 	}
2311*cdf0e10cSrcweir 	updateSelectionOverlay();
2312*cdf0e10cSrcweir }
2313*cdf0e10cSrcweir 
2314*cdf0e10cSrcweir 
2315*cdf0e10cSrcweir // --------------------------------------------------------------------
2316*cdf0e10cSrcweir 
2317*cdf0e10cSrcweir void SvxTableController::SetAttrToSelectedCells(const SfxItemSet& rAttr, bool bReplaceAll)
2318*cdf0e10cSrcweir {
2319*cdf0e10cSrcweir 	if( mxTable.is() )
2320*cdf0e10cSrcweir 	{
2321*cdf0e10cSrcweir 		const bool bUndo = mpModel && mpModel->IsUndoEnabled();
2322*cdf0e10cSrcweir 
2323*cdf0e10cSrcweir 		if( bUndo )
2324*cdf0e10cSrcweir 			mpModel->BegUndo( ImpGetResStr(STR_TABLE_NUMFORMAT) );
2325*cdf0e10cSrcweir 
2326*cdf0e10cSrcweir 		CellPos aStart, aEnd;
2327*cdf0e10cSrcweir 		getSelectedCells( aStart, aEnd );
2328*cdf0e10cSrcweir 
2329*cdf0e10cSrcweir 		SfxItemSet aAttr(*rAttr.GetPool(), rAttr.GetRanges());
2330*cdf0e10cSrcweir 		aAttr.Put(rAttr, sal_True);
2331*cdf0e10cSrcweir 
2332*cdf0e10cSrcweir 		const bool bFrame = (rAttr.GetItemState( SDRATTR_TABLE_BORDER ) == SFX_ITEM_SET) || (rAttr.GetItemState( SDRATTR_TABLE_BORDER_INNER ) == SFX_ITEM_SET);
2333*cdf0e10cSrcweir 
2334*cdf0e10cSrcweir 		if( bFrame )
2335*cdf0e10cSrcweir 		{
2336*cdf0e10cSrcweir 			aAttr.ClearItem( SDRATTR_TABLE_BORDER );
2337*cdf0e10cSrcweir 			aAttr.ClearItem( SDRATTR_TABLE_BORDER_INNER );
2338*cdf0e10cSrcweir 		}
2339*cdf0e10cSrcweir 
2340*cdf0e10cSrcweir 		for( sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++ )
2341*cdf0e10cSrcweir 		{
2342*cdf0e10cSrcweir 			for( sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++ )
2343*cdf0e10cSrcweir 			{
2344*cdf0e10cSrcweir 				CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
2345*cdf0e10cSrcweir 				if( xCell.is() )
2346*cdf0e10cSrcweir 				{
2347*cdf0e10cSrcweir 					if( bUndo )
2348*cdf0e10cSrcweir 						xCell->AddUndo();
2349*cdf0e10cSrcweir 					xCell->SetMergedItemSetAndBroadcast(aAttr, bReplaceAll);
2350*cdf0e10cSrcweir 				}
2351*cdf0e10cSrcweir 			}
2352*cdf0e10cSrcweir 		}
2353*cdf0e10cSrcweir 
2354*cdf0e10cSrcweir 		if( bFrame )
2355*cdf0e10cSrcweir 		{
2356*cdf0e10cSrcweir 			ApplyBorderAttr( rAttr );
2357*cdf0e10cSrcweir 		}
2358*cdf0e10cSrcweir 
2359*cdf0e10cSrcweir 		UpdateTableShape();
2360*cdf0e10cSrcweir 
2361*cdf0e10cSrcweir 		if( bUndo )
2362*cdf0e10cSrcweir 			mpModel->EndUndo();
2363*cdf0e10cSrcweir 
2364*cdf0e10cSrcweir 	}
2365*cdf0e10cSrcweir }
2366*cdf0e10cSrcweir 
2367*cdf0e10cSrcweir // --------------------------------------------------------------------
2368*cdf0e10cSrcweir 
2369*cdf0e10cSrcweir bool SvxTableController::GetAttributes(SfxItemSet& rTargetSet, bool bOnlyHardAttr) const
2370*cdf0e10cSrcweir {
2371*cdf0e10cSrcweir 	if( mxTableObj.is() && hasSelectedCells() )
2372*cdf0e10cSrcweir 	{
2373*cdf0e10cSrcweir 		MergeAttrFromSelectedCells( rTargetSet, bOnlyHardAttr );
2374*cdf0e10cSrcweir 
2375*cdf0e10cSrcweir 		if( mpView->IsTextEdit() )
2376*cdf0e10cSrcweir 		{
2377*cdf0e10cSrcweir 			if( mxTableObj->GetOutlinerParaObject() )
2378*cdf0e10cSrcweir 				rTargetSet.Put( SvxScriptTypeItem( mxTableObj->GetOutlinerParaObject()->GetTextObject().GetScriptType() ) );
2379*cdf0e10cSrcweir 
2380*cdf0e10cSrcweir 			OutlinerView* pTextEditOutlinerView = mpView->GetTextEditOutlinerView();
2381*cdf0e10cSrcweir 			if(pTextEditOutlinerView)
2382*cdf0e10cSrcweir 			{
2383*cdf0e10cSrcweir 				// FALSE= InvalidItems nicht al Default, sondern als "Loecher" betrachten
2384*cdf0e10cSrcweir 				rTargetSet.Put(pTextEditOutlinerView->GetAttribs(), sal_False);
2385*cdf0e10cSrcweir 				rTargetSet.Put( SvxScriptTypeItem( pTextEditOutlinerView->GetSelectedScriptType() ), sal_False );
2386*cdf0e10cSrcweir 			}
2387*cdf0e10cSrcweir 		}
2388*cdf0e10cSrcweir 
2389*cdf0e10cSrcweir 		return true;
2390*cdf0e10cSrcweir 	}
2391*cdf0e10cSrcweir 	else
2392*cdf0e10cSrcweir 	{
2393*cdf0e10cSrcweir 		return false;
2394*cdf0e10cSrcweir 	}
2395*cdf0e10cSrcweir }
2396*cdf0e10cSrcweir 
2397*cdf0e10cSrcweir // --------------------------------------------------------------------
2398*cdf0e10cSrcweir 
2399*cdf0e10cSrcweir bool SvxTableController::SetAttributes(const SfxItemSet& rSet, bool bReplaceAll)
2400*cdf0e10cSrcweir {
2401*cdf0e10cSrcweir 	if( mbCellSelectionMode || mpView->IsTextEdit()  )
2402*cdf0e10cSrcweir 	{
2403*cdf0e10cSrcweir 		SetAttrToSelectedCells( rSet, bReplaceAll );
2404*cdf0e10cSrcweir 		return true;
2405*cdf0e10cSrcweir 	}
2406*cdf0e10cSrcweir 	return false;
2407*cdf0e10cSrcweir }
2408*cdf0e10cSrcweir 
2409*cdf0e10cSrcweir // --------------------------------------------------------------------
2410*cdf0e10cSrcweir 
2411*cdf0e10cSrcweir bool SvxTableController::GetMarkedObjModel( SdrPage* pNewPage )
2412*cdf0e10cSrcweir {
2413*cdf0e10cSrcweir 	if( mxTableObj.is() && mbCellSelectionMode && pNewPage ) try
2414*cdf0e10cSrcweir 	{
2415*cdf0e10cSrcweir 		::sdr::table::SdrTableObj& rTableObj = *static_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
2416*cdf0e10cSrcweir 
2417*cdf0e10cSrcweir 		CellPos aStart, aEnd;
2418*cdf0e10cSrcweir 		getSelectedCells( aStart, aEnd );
2419*cdf0e10cSrcweir 
2420*cdf0e10cSrcweir 		SdrTableObj* pNewTableObj = rTableObj.CloneRange( aStart, aEnd );
2421*cdf0e10cSrcweir 
2422*cdf0e10cSrcweir 		pNewTableObj->SetPage( pNewPage );
2423*cdf0e10cSrcweir 		pNewTableObj->SetModel( pNewPage->GetModel() );
2424*cdf0e10cSrcweir 
2425*cdf0e10cSrcweir 		SdrInsertReason aReason(SDRREASON_VIEWCALL);
2426*cdf0e10cSrcweir 		pNewPage->InsertObject(pNewTableObj,CONTAINER_APPEND,&aReason);
2427*cdf0e10cSrcweir 
2428*cdf0e10cSrcweir 		return true;
2429*cdf0e10cSrcweir 	}
2430*cdf0e10cSrcweir 	catch( Exception& )
2431*cdf0e10cSrcweir 	{
2432*cdf0e10cSrcweir 		DBG_ERROR( "svx::SvxTableController::GetMarkedObjModel(), exception caught!" );
2433*cdf0e10cSrcweir 	}
2434*cdf0e10cSrcweir 	return false;
2435*cdf0e10cSrcweir }
2436*cdf0e10cSrcweir 
2437*cdf0e10cSrcweir // --------------------------------------------------------------------
2438*cdf0e10cSrcweir 
2439*cdf0e10cSrcweir bool SvxTableController::PasteObjModel( const SdrModel& rModel )
2440*cdf0e10cSrcweir {
2441*cdf0e10cSrcweir 	if( mxTableObj.is() && mpView && (rModel.GetPageCount() >= 1) )
2442*cdf0e10cSrcweir 	{
2443*cdf0e10cSrcweir 		const SdrPage* pPastePage = rModel.GetPage(0);
2444*cdf0e10cSrcweir 		if( pPastePage && pPastePage->GetObjCount() == 1 )
2445*cdf0e10cSrcweir 		{
2446*cdf0e10cSrcweir 			SdrTableObj* pPasteTableObj = dynamic_cast< SdrTableObj* >( pPastePage->GetObj(0) );
2447*cdf0e10cSrcweir 			if( pPasteTableObj )
2448*cdf0e10cSrcweir 			{
2449*cdf0e10cSrcweir 				return PasteObject( pPasteTableObj );
2450*cdf0e10cSrcweir 			}
2451*cdf0e10cSrcweir 		}
2452*cdf0e10cSrcweir 	}
2453*cdf0e10cSrcweir 
2454*cdf0e10cSrcweir 	return false;
2455*cdf0e10cSrcweir }
2456*cdf0e10cSrcweir 
2457*cdf0e10cSrcweir // --------------------------------------------------------------------
2458*cdf0e10cSrcweir 
2459*cdf0e10cSrcweir bool SvxTableController::PasteObject( SdrTableObj* pPasteTableObj )
2460*cdf0e10cSrcweir {
2461*cdf0e10cSrcweir 	if( !pPasteTableObj )
2462*cdf0e10cSrcweir 		return false;
2463*cdf0e10cSrcweir 
2464*cdf0e10cSrcweir 	Reference< XTable > xPasteTable( pPasteTableObj->getTable() );
2465*cdf0e10cSrcweir 	if( !xPasteTable.is() )
2466*cdf0e10cSrcweir 		return false;
2467*cdf0e10cSrcweir 
2468*cdf0e10cSrcweir 	if( !mxTable.is() )
2469*cdf0e10cSrcweir 		return false;
2470*cdf0e10cSrcweir 
2471*cdf0e10cSrcweir 	sal_Int32 nPasteColumns = xPasteTable->getColumnCount();
2472*cdf0e10cSrcweir 	sal_Int32 nPasteRows = xPasteTable->getRowCount();
2473*cdf0e10cSrcweir 
2474*cdf0e10cSrcweir 	CellPos aStart, aEnd;
2475*cdf0e10cSrcweir 	getSelectedCells( aStart, aEnd );
2476*cdf0e10cSrcweir 
2477*cdf0e10cSrcweir 	if( mpView->IsTextEdit() )
2478*cdf0e10cSrcweir 		mpView->SdrEndTextEdit(sal_True);
2479*cdf0e10cSrcweir 
2480*cdf0e10cSrcweir 	sal_Int32 nColumns = mxTable->getColumnCount();
2481*cdf0e10cSrcweir 	sal_Int32 nRows = mxTable->getRowCount();
2482*cdf0e10cSrcweir 
2483*cdf0e10cSrcweir 	const sal_Int32 nMissing = nPasteRows - ( nRows - aStart.mnRow );
2484*cdf0e10cSrcweir 	if( nMissing > 0 )
2485*cdf0e10cSrcweir 	{
2486*cdf0e10cSrcweir 		Reference< XTableRows > xRows( mxTable->getRows() );
2487*cdf0e10cSrcweir 		xRows->insertByIndex( nRows, nMissing );
2488*cdf0e10cSrcweir 		nRows = mxTable->getRowCount();
2489*cdf0e10cSrcweir 	}
2490*cdf0e10cSrcweir 
2491*cdf0e10cSrcweir 	nPasteRows = std::min( nPasteRows, nRows - aStart.mnRow );
2492*cdf0e10cSrcweir 	nPasteColumns = std::min( nPasteColumns, nColumns - aStart.mnCol );
2493*cdf0e10cSrcweir 
2494*cdf0e10cSrcweir 	// copy cell contents
2495*cdf0e10cSrcweir 	for( sal_Int32 nRow = 0; nRow < nPasteRows; ++nRow )
2496*cdf0e10cSrcweir 	{
2497*cdf0e10cSrcweir 		for( sal_Int32 nCol = 0; nCol < nPasteColumns; ++nCol )
2498*cdf0e10cSrcweir 		{
2499*cdf0e10cSrcweir 			CellRef xTargetCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( aStart.mnCol + nCol, aStart.mnRow + nRow ).get() ) );
2500*cdf0e10cSrcweir 			if( xTargetCell.is() && !xTargetCell->isMerged() )
2501*cdf0e10cSrcweir 			{
2502*cdf0e10cSrcweir 				xTargetCell->AddUndo();
2503*cdf0e10cSrcweir 				xTargetCell->cloneFrom( dynamic_cast< Cell* >( xPasteTable->getCellByPosition( nCol, nRow ).get() ) );
2504*cdf0e10cSrcweir 				nCol += xTargetCell->getColumnSpan() - 1;
2505*cdf0e10cSrcweir 			}
2506*cdf0e10cSrcweir 		}
2507*cdf0e10cSrcweir 	}
2508*cdf0e10cSrcweir 
2509*cdf0e10cSrcweir 	UpdateTableShape();
2510*cdf0e10cSrcweir 
2511*cdf0e10cSrcweir 	return true;
2512*cdf0e10cSrcweir }
2513*cdf0e10cSrcweir 
2514*cdf0e10cSrcweir bool SvxTableController::TakeFormatPaintBrush( boost::shared_ptr< SfxItemSet >& /*rFormatSet*/  )
2515*cdf0e10cSrcweir {
2516*cdf0e10cSrcweir     // SdrView::TakeFormatPaintBrush() is enough
2517*cdf0e10cSrcweir     return false;
2518*cdf0e10cSrcweir }
2519*cdf0e10cSrcweir 
2520*cdf0e10cSrcweir bool SvxTableController::ApplyFormatPaintBrush( SfxItemSet& rFormatSet, bool bNoCharacterFormats, bool bNoParagraphFormats )
2521*cdf0e10cSrcweir {
2522*cdf0e10cSrcweir 	if( mbCellSelectionMode )
2523*cdf0e10cSrcweir 	{
2524*cdf0e10cSrcweir     	SdrTextObj* pTableObj = dynamic_cast<SdrTextObj*>( mxTableObj.get() );
2525*cdf0e10cSrcweir     	if( !pTableObj )
2526*cdf0e10cSrcweir     	    return false;
2527*cdf0e10cSrcweir 
2528*cdf0e10cSrcweir 		const bool bUndo = mpModel && mpModel->IsUndoEnabled();
2529*cdf0e10cSrcweir 
2530*cdf0e10cSrcweir 		if( bUndo )
2531*cdf0e10cSrcweir 			mpModel->BegUndo( ImpGetResStr(STR_TABLE_NUMFORMAT) );
2532*cdf0e10cSrcweir 
2533*cdf0e10cSrcweir 		CellPos aStart, aEnd;
2534*cdf0e10cSrcweir 		getSelectedCells( aStart, aEnd );
2535*cdf0e10cSrcweir 
2536*cdf0e10cSrcweir 		SfxItemSet aAttr(*rFormatSet.GetPool(), rFormatSet.GetRanges());
2537*cdf0e10cSrcweir 		aAttr.Put(rFormatSet, sal_True);
2538*cdf0e10cSrcweir 
2539*cdf0e10cSrcweir 		const bool bFrame = (rFormatSet.GetItemState( SDRATTR_TABLE_BORDER ) == SFX_ITEM_SET) || (rFormatSet.GetItemState( SDRATTR_TABLE_BORDER_INNER ) == SFX_ITEM_SET);
2540*cdf0e10cSrcweir 
2541*cdf0e10cSrcweir 		if( bFrame )
2542*cdf0e10cSrcweir 		{
2543*cdf0e10cSrcweir 			aAttr.ClearItem( SDRATTR_TABLE_BORDER );
2544*cdf0e10cSrcweir 			aAttr.ClearItem( SDRATTR_TABLE_BORDER_INNER );
2545*cdf0e10cSrcweir 		}
2546*cdf0e10cSrcweir 
2547*cdf0e10cSrcweir         const sal_uInt16* pRanges = rFormatSet.GetRanges();
2548*cdf0e10cSrcweir         bool bTextOnly = true;
2549*cdf0e10cSrcweir 
2550*cdf0e10cSrcweir         while( *pRanges )
2551*cdf0e10cSrcweir         {
2552*cdf0e10cSrcweir             if( (*pRanges != EE_PARA_START) && (*pRanges != EE_CHAR_START) )
2553*cdf0e10cSrcweir             {
2554*cdf0e10cSrcweir                 bTextOnly = true;
2555*cdf0e10cSrcweir                 break;
2556*cdf0e10cSrcweir             }
2557*cdf0e10cSrcweir             pRanges += 2;
2558*cdf0e10cSrcweir         }
2559*cdf0e10cSrcweir 
2560*cdf0e10cSrcweir         const bool bReplaceAll = false;
2561*cdf0e10cSrcweir 		for( sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++ )
2562*cdf0e10cSrcweir 		{
2563*cdf0e10cSrcweir 			for( sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++ )
2564*cdf0e10cSrcweir 			{
2565*cdf0e10cSrcweir 				CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
2566*cdf0e10cSrcweir 				if( xCell.is() )
2567*cdf0e10cSrcweir 				{
2568*cdf0e10cSrcweir 					if( bUndo )
2569*cdf0e10cSrcweir 						xCell->AddUndo();
2570*cdf0e10cSrcweir 				    if( !bTextOnly )
2571*cdf0e10cSrcweir 					    xCell->SetMergedItemSetAndBroadcast(aAttr, bReplaceAll);
2572*cdf0e10cSrcweir 
2573*cdf0e10cSrcweir                     SdrText* pText = static_cast< SdrText* >( xCell.get() );
2574*cdf0e10cSrcweir                     mpView->ApplyFormatPaintBrushToText( rFormatSet, *pTableObj, pText, bNoCharacterFormats, bNoParagraphFormats );
2575*cdf0e10cSrcweir 				}
2576*cdf0e10cSrcweir 			}
2577*cdf0e10cSrcweir 		}
2578*cdf0e10cSrcweir 
2579*cdf0e10cSrcweir 		if( bFrame )
2580*cdf0e10cSrcweir 		{
2581*cdf0e10cSrcweir 			ApplyBorderAttr( rFormatSet );
2582*cdf0e10cSrcweir 		}
2583*cdf0e10cSrcweir 
2584*cdf0e10cSrcweir 		UpdateTableShape();
2585*cdf0e10cSrcweir 
2586*cdf0e10cSrcweir 		if( bUndo )
2587*cdf0e10cSrcweir 			mpModel->EndUndo();
2588*cdf0e10cSrcweir 
2589*cdf0e10cSrcweir 	    return true;
2590*cdf0e10cSrcweir 
2591*cdf0e10cSrcweir 	}
2592*cdf0e10cSrcweir     return false;
2593*cdf0e10cSrcweir }
2594*cdf0e10cSrcweir 
2595*cdf0e10cSrcweir 
2596*cdf0e10cSrcweir // --------------------------------------------------------------------
2597*cdf0e10cSrcweir 
2598*cdf0e10cSrcweir IMPL_LINK( SvxTableController, UpdateHdl, void *, EMPTYARG )
2599*cdf0e10cSrcweir {
2600*cdf0e10cSrcweir 	mnUpdateEvent = 0;
2601*cdf0e10cSrcweir 
2602*cdf0e10cSrcweir 	if( mbCellSelectionMode )
2603*cdf0e10cSrcweir 	{
2604*cdf0e10cSrcweir 		CellPos aStart( maCursorFirstPos );
2605*cdf0e10cSrcweir 		CellPos aEnd( maCursorLastPos );
2606*cdf0e10cSrcweir 		checkCell(aStart);
2607*cdf0e10cSrcweir 		checkCell(aEnd);
2608*cdf0e10cSrcweir 		if( aStart != maCursorFirstPos  || aEnd != maCursorLastPos )
2609*cdf0e10cSrcweir 		{
2610*cdf0e10cSrcweir 			setSelectedCells( aStart, aEnd );
2611*cdf0e10cSrcweir 		}
2612*cdf0e10cSrcweir 	}
2613*cdf0e10cSrcweir 	updateSelectionOverlay();
2614*cdf0e10cSrcweir 
2615*cdf0e10cSrcweir 	return 0;
2616*cdf0e10cSrcweir }
2617*cdf0e10cSrcweir 
2618*cdf0e10cSrcweir } }
2619