1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: tablecontroller.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
34 #include "tablecontroller.hxx"
36 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
37 #include <com/sun/star/container/XIndexAccess.hpp>
39 #include <com/sun/star/beans/XPropertySet.hpp>
40 #include <com/sun/star/table/XMergeableCellRange.hpp>
41 #include <com/sun/star/table/XMergeableCell.hpp>
43 #include <sal/config.h>
45 #include <vcl/svapp.hxx>
46 #include <svtools/whiter.hxx>
48 #include <sfx2/request.hxx>
50 #include <svx/scripttypeitem.hxx>
51 #include <svx/svdotable.hxx>
52 #include <svx/sdr/overlay/overlayobjectcell.hxx>
53 #include <svx/sdr/overlay/overlaymanager.hxx>
54 #include <svx/svxids.hrc>
55 #include <svx/outlobj.hxx>
56 #include <svx/svdoutl.hxx>
57 #include <svx/svdpagv.hxx>
58 #include <svx/svdetc.hxx>
59 #include <svx/editobj.hxx>
60 #include "editstat.hxx"
61 #include "unolingu.hxx"
62 #include "svx/sdrpagewindow.hxx"
63 #include <svx/selectioncontroller.hxx>
64 #include <svx/svdmodel.hxx>
65 #include "sdrpaintwindow.hxx"
66 #include <svx/svxdlg.hxx>
67 #include <svx/boxitem.hxx>
69 #include <svx/borderline.hxx>
70 #include <svx/colritem.hxx>
71 #include "bolnitem.hxx"
73 #include "svdglob.hxx"
74 #include "svx/svdpage.hxx"
75 #include "tableundo.hxx"
76 #include "tablelayouter.hxx"
78 using ::rtl::OUString
;
79 using namespace ::sdr::table
;
80 using namespace ::com::sun::star
;
81 using namespace ::com::sun::star::uno
;
82 using namespace ::com::sun::star::table
;
83 using namespace ::com::sun::star::beans
;
84 using namespace ::com::sun::star::container
;
85 using namespace ::com::sun::star::text
;
86 using namespace ::com::sun::star::style
;
88 namespace sdr
{ namespace table
{
90 // --------------------------------------------------------------------
91 // class SvxTableControllerModifyListener
92 // --------------------------------------------------------------------
94 class SvxTableControllerModifyListener
: public ::cppu::WeakImplHelper1
< ::com::sun::star::util::XModifyListener
>
97 SvxTableControllerModifyListener( SvxTableController
* pController
)
98 : mpController( pController
) {}
101 virtual void SAL_CALL
modified( const ::com::sun::star::lang::EventObject
& aEvent
) throw (::com::sun::star::uno::RuntimeException
);
104 virtual void SAL_CALL
disposing( const ::com::sun::star::lang::EventObject
& Source
) throw (::com::sun::star::uno::RuntimeException
);
106 SvxTableController
* mpController
;
109 // --------------------------------------------------------------------
111 // --------------------------------------------------------------------
113 void SAL_CALL
SvxTableControllerModifyListener::modified( const ::com::sun::star::lang::EventObject
& ) throw (::com::sun::star::uno::RuntimeException
)
116 mpController
->onTableModified();
119 // --------------------------------------------------------------------
121 // --------------------------------------------------------------------
123 void SAL_CALL
SvxTableControllerModifyListener::disposing( const ::com::sun::star::lang::EventObject
& ) throw (::com::sun::star::uno::RuntimeException
)
128 // --------------------------------------------------------------------
129 // class SvxTableController
130 // --------------------------------------------------------------------
132 rtl::Reference
< sdr::SelectionController
> CreateTableController( SdrObjEditView
* pView
, const SdrObject
* pObj
, const rtl::Reference
< sdr::SelectionController
>& xRefController
)
134 return SvxTableController::create( pView
, pObj
, xRefController
);
137 // --------------------------------------------------------------------
139 rtl::Reference
< sdr::SelectionController
> SvxTableController::create( SdrObjEditView
* pView
, const SdrObject
* pObj
, const rtl::Reference
< sdr::SelectionController
>& xRefController
)
141 if( xRefController
.is() )
143 SvxTableController
* pController
= dynamic_cast< SvxTableController
* >( xRefController
.get() );
144 if( pController
&& (pController
->mxTableObj
.get() == pObj
) && (pController
->mpView
== pView
) )
145 return xRefController
;
147 return new SvxTableController( pView
, pObj
);
150 // --------------------------------------------------------------------
152 SvxTableController::SvxTableController( SdrObjEditView
* pView
, const SdrObject
* pObj
)
153 : mbCellSelectionMode(false)
154 , mbLeftButtonDown(false)
155 , mpSelectionOverlay(0)
156 , mpView( dynamic_cast< SdrView
* >( pView
) )
157 , mxTableObj( dynamic_cast< SdrTableObj
* >( const_cast< SdrObject
* >( pObj
) ) )
162 mpModel
= pObj
->GetModel();
164 if( mxTableObj
.is() )
166 static_cast< const SdrTableObj
* >( pObj
)->getActiveCellPos( maCursorFirstPos
);
167 maCursorLastPos
= maCursorFirstPos
;
169 Reference
< XTable
> xTable( static_cast< const SdrTableObj
* >( pObj
)->getTable() );
172 mxModifyListener
= new SvxTableControllerModifyListener( this );
173 xTable
->addModifyListener( mxModifyListener
);
175 mxTable
.set( dynamic_cast< TableModel
* >( xTable
.get() ) );
180 // --------------------------------------------------------------------
182 SvxTableController::~SvxTableController()
186 Application::RemoveUserEvent( mnUpdateEvent
);
189 if( mxModifyListener
.is() && mxTableObj
.get() )
191 Reference
< XTable
> xTable( static_cast< SdrTableObj
* >( mxTableObj
.get() )->getTable() );
194 xTable
->removeModifyListener( mxModifyListener
);
195 mxModifyListener
.clear();
200 // --------------------------------------------------------------------
202 const sal_uInt16 ACTION_NONE
= 0;
203 const sal_uInt16 ACTION_GOTO_FIRST_CELL
= 1;
204 const sal_uInt16 ACTION_GOTO_FIRST_COLUMN
= 2;
205 const sal_uInt16 ACTION_GOTO_FIRST_ROW
= 3;
206 const sal_uInt16 ACTION_GOTO_LEFT_CELL
= 4;
207 const sal_uInt16 ACTION_GOTO_UP_CELL
= 5;
208 const sal_uInt16 ACTION_GOTO_RIGHT_CELL
= 6;
209 const sal_uInt16 ACTION_GOTO_DOWN_CELL
= 7;
210 const sal_uInt16 ACTION_GOTO_LAST_CELL
= 8;
211 const sal_uInt16 ACTION_GOTO_LAST_COLUMN
= 9;
212 const sal_uInt16 ACTION_GOTO_LAST_ROW
= 10;
213 const sal_uInt16 ACTION_EDIT_CELL
= 11;
214 const sal_uInt16 ACTION_STOP_TEXT_EDIT
= 12;
215 const sal_uInt16 ACTION_REMOVE_SELECTION
= 13;
216 const sal_uInt16 ACTION_START_SELECTION
= 14;
217 const sal_uInt16 ACTION_HANDLED_BY_VIEW
= 15;
218 const sal_uInt16 ACTION_TAB
= 18;
220 bool SvxTableController::onKeyInput(const KeyEvent
& rKEvt
, Window
* pWindow
)
222 if( !checkTableObject() )
225 // check if we are read only
226 if( mpModel
&& mpModel
->IsReadOnly())
228 switch( rKEvt
.GetKeyCode().GetCode() )
233 case awt::Key::RIGHT
:
241 case awt::Key::ESCAPE
:
245 // tell the view we eat the event, no further processing needed
250 sal_uInt16 nAction
= getKeyboardAction( rKEvt
, pWindow
);
252 return executeAction( nAction
, ( rKEvt
.GetKeyCode().IsShift() ) ? sal_True
: sal_False
, pWindow
);
255 // --------------------------------------------------------------------
256 // ::com::sun::star::awt::XMouseClickHandler:
257 // --------------------------------------------------------------------
259 bool SvxTableController::onMouseButtonDown(const MouseEvent
& rMEvt
, Window
* pWindow
)
261 if( !pWindow
|| !checkTableObject() )
265 if( !rMEvt
.IsRight() && mpView
->PickAnything(rMEvt
,SDRMOUSEBUTTONDOWN
, aVEvt
) == SDRHIT_HANDLE
)
268 TableHitKind eHit
= static_cast< SdrTableObj
* >(mxTableObj
.get())->CheckTableHit( pWindow
->PixelToLogic(rMEvt
.GetPosPixel()), maMouseDownPos
.mnCol
, maMouseDownPos
.mnRow
, 0 );
270 mbLeftButtonDown
= (rMEvt
.GetClicks() == 1) && rMEvt
.IsLeft();
272 if( eHit
== SDRTABLEHIT_CELL
)
274 StartSelection( maMouseDownPos
);
278 if( rMEvt
.IsRight() && eHit
!= SDRTABLEHIT_NONE
)
279 return true; // right click will become context menu
281 // for cell selektion with the mouse remember our first hit
282 if( mbLeftButtonDown
)
286 Point
aPnt(rMEvt
.GetPosPixel());
288 aPnt
=pWindow
->PixelToLogic(aPnt
);
290 SdrHdl
* pHdl
= mpView
->PickHandle(aPnt
);
294 mbLeftButtonDown
= false;
298 ::sdr::table::SdrTableObj
* pTableObj
= dynamic_cast< ::sdr::table::SdrTableObj
* >( mxTableObj
.get() );
300 if( !pWindow
|| !pTableObj
|| eHit
== SDRTABLEHIT_NONE
)
302 mbLeftButtonDown
= false;
310 // --------------------------------------------------------------------
312 bool SvxTableController::onMouseButtonUp(const MouseEvent
& rMEvt
, Window
* /*pWin*/)
314 if( !checkTableObject() )
317 mbLeftButtonDown
= false;
319 if( rMEvt
.GetClicks() == 2 )
325 // --------------------------------------------------------------------
327 bool SvxTableController::onMouseMove(const MouseEvent
& rMEvt
, Window
* pWindow
)
329 if( !checkTableObject() )
338 SdrTableObj
* pTableObj
= dynamic_cast< SdrTableObj
* >( mxTableObj
.get() );
340 if( mbLeftButtonDown
&& pTableObj
&& pTableObj
->CheckTableHit( pWindow
->PixelToLogic(rMEvt
.GetPosPixel()), aPos
.mnCol
, aPos
.mnRow
, 0 ) != SDRTABLEHIT_NONE
)
342 if(aPos
!= maMouseDownPos
)
344 if( mbCellSelectionMode
)
346 setSelectedCells( maMouseDownPos
, aPos
);
351 StartSelection( maMouseDownPos
);
354 else if( mbCellSelectionMode
)
356 UpdateSelection( aPos
);
363 // --------------------------------------------------------------------
365 void SvxTableController::onSelectionHasChanged()
367 bool bSelected
= false;
369 SdrTableObj
* pTableObj
= dynamic_cast< SdrTableObj
* >( mxTableObj
.get() );
370 if( pTableObj
&& pTableObj
->IsTextEditActive() )
372 pTableObj
->getActiveCellPos( maCursorFirstPos
);
373 maCursorLastPos
= maCursorFirstPos
;
374 mbCellSelectionMode
= false;
378 const SdrMarkList
& rMarkList
= mpView
->GetMarkedObjectList();
379 if( rMarkList
.GetMarkCount() == 1 )
380 bSelected
= mxTableObj
.get() == rMarkList
.GetMark(0)->GetMarkedSdrObj();
385 updateSelectionOverlay();
389 destroySelectionOverlay();
393 // --------------------------------------------------------------------
395 void SvxTableController::GetState( SfxItemSet
& rSet
)
397 if( !mxTable
.is() || !mxTableObj
.is() || !mxTableObj
->GetModel() )
400 SfxItemSet
* pSet
= 0;
402 bool bVertDone
= false;
404 // Iterate over all requested items in the set.
405 SfxWhichIter
aIter( rSet
);
406 USHORT nWhich
= aIter
.FirstWhich();
411 case SID_TABLE_VERT_BOTTOM
:
412 case SID_TABLE_VERT_CENTER
:
413 case SID_TABLE_VERT_NONE
:
415 if( !mxTable
.is() || !mxTableObj
->GetModel() )
417 rSet
.DisableItem(nWhich
);
423 pSet
= new SfxItemSet( mxTableObj
->GetModel()->GetItemPool() );
424 MergeAttrFromSelectedCells(*pSet
, FALSE
);
427 SdrTextVertAdjust eAdj
= SDRTEXTVERTADJUST_BLOCK
;
429 if( pSet
->GetItemState( SDRATTR_TEXT_VERTADJUST
) != SFX_ITEM_DONTCARE
)
430 eAdj
= ((SdrTextVertAdjustItem
&)(pSet
->Get(SDRATTR_TEXT_VERTADJUST
))).GetValue();
432 rSet
.Put(SfxBoolItem(SID_TABLE_VERT_BOTTOM
, eAdj
== SDRTEXTVERTADJUST_BOTTOM
));
433 rSet
.Put(SfxBoolItem(SID_TABLE_VERT_CENTER
, eAdj
== SDRTEXTVERTADJUST_CENTER
));
434 rSet
.Put(SfxBoolItem(SID_TABLE_VERT_NONE
, eAdj
== SDRTEXTVERTADJUST_TOP
));
439 case SID_TABLE_DELETE_ROW
:
440 if( !mxTable
.is() || !hasSelectedCells() || (mxTable
->getRowCount() <= 1) )
441 rSet
.DisableItem(SID_TABLE_DELETE_ROW
);
443 case SID_TABLE_DELETE_COL
:
444 if( !mxTable
.is() || !hasSelectedCells() || (mxTable
->getColumnCount() <= 1) )
445 rSet
.DisableItem(SID_TABLE_DELETE_COL
);
447 case SID_TABLE_MERGE_CELLS
:
448 if( !mxTable
.is() || !hasSelectedCells() )
449 rSet
.DisableItem(SID_TABLE_MERGE_CELLS
);
451 case SID_TABLE_SPLIT_CELLS
:
452 if( !hasSelectedCells() || !mxTable
.is() )
453 rSet
.DisableItem(SID_TABLE_SPLIT_CELLS
);
456 case SID_OPTIMIZE_TABLE
:
457 case SID_TABLE_DISTRIBUTE_COLUMNS
:
458 case SID_TABLE_DISTRIBUTE_ROWS
:
460 bool bDistributeColumns
= false;
461 bool bDistributeRows
= false;
464 CellPos aStart
, aEnd
;
465 getSelectedCells( aStart
, aEnd
);
467 bDistributeColumns
= aStart
.mnCol
!= aEnd
.mnCol
;
468 bDistributeRows
= aStart
.mnRow
!= aEnd
.mnRow
;
470 if( !bDistributeColumns
&& !bDistributeRows
)
471 rSet
.DisableItem(SID_OPTIMIZE_TABLE
);
472 if( !bDistributeColumns
)
473 rSet
.DisableItem(SID_TABLE_DISTRIBUTE_COLUMNS
);
474 if( !bDistributeRows
)
475 rSet
.DisableItem(SID_TABLE_DISTRIBUTE_ROWS
);
480 case SID_TABLE_SORT_DIALOG
:
481 case SID_TABLE_AUTOSUM
:
482 // if( !mxTable.is() )
483 // rSet.DisableItem( nWhich );
488 nWhich
= aIter
.NextWhich();
494 // --------------------------------------------------------------------
496 void SvxTableController::onInsert( sal_uInt16 nSId
, const SfxItemSet
* pArgs
)
498 ::sdr::table::SdrTableObj
* pTableObj
= dynamic_cast< ::sdr::table::SdrTableObj
* >( mxTableObj
.get() );
502 if( mxTable
.is() ) try
505 bool bInsertAfter
= true;
506 sal_uInt16 nCount
= 0;
509 const SfxPoolItem
* pItem
= 0;
510 pArgs
->GetItemState(nSId
, FALSE
, &pItem
);
513 nCount
= ((const SfxInt16Item
* )pItem
)->GetValue();
514 if(SFX_ITEM_SET
== pArgs
->GetItemState(SID_TABLE_PARAM_INSERT_AFTER
, TRUE
, &pItem
))
515 bInsertAfter
= ((const SfxBoolItem
* )pItem
)->GetValue();
519 CellPos aStart
, aEnd
;
520 if( hasSelectedCells() )
522 getSelectedCells( aStart
, aEnd
);
528 aStart
.mnCol
= mxTable
->getColumnCount() - 1;
529 aStart
.mnRow
= mxTable
->getRowCount() - 1;
534 if( pTableObj
->IsTextEditActive() )
535 mpView
->SdrEndTextEdit(sal_True
);
539 const OUString
sSize( RTL_CONSTASCII_USTRINGPARAM( "Size" ) );
541 const bool bUndo
= mpModel
&& mpModel
->IsUndoEnabled();
545 case SID_TABLE_INSERT_COL
:
547 TableModelNotifyGuard
aGuard( mxTable
.get() );
551 mpModel
->BegUndo( ImpGetResStr(STR_TABLE_INSCOL
) );
552 mpModel
->AddUndo( mpModel
->GetSdrUndoFactory().CreateUndoGeoObject(*pTableObj
) );
555 Reference
< XTableColumns
> xCols( mxTable
->getColumns() );
556 const sal_Int32 nNewColumns
= (nCount
== 0) ? (aEnd
.mnCol
- aStart
.mnCol
+ 1) : nCount
;
557 const sal_Int32 nNewStartColumn
= aEnd
.mnCol
+ (bInsertAfter
? 1 : 0);
558 xCols
->insertByIndex( nNewStartColumn
, nNewColumns
);
560 for( sal_Int32 nOffset
= 0; nOffset
< nNewColumns
; nOffset
++ )
562 Reference
< XPropertySet
>( xCols
->getByIndex( aEnd
.mnCol
+ nOffset
+ 1 ), UNO_QUERY_THROW
)->
563 setPropertyValue( sSize
,
564 Reference
< XPropertySet
>( xCols
->getByIndex( aStart
.mnCol
+ nOffset
), UNO_QUERY_THROW
)->
565 getPropertyValue( sSize
) );
571 aStart
.mnCol
= nNewStartColumn
;
573 aEnd
.mnCol
= aStart
.mnCol
+ nNewColumns
- 1;
574 aEnd
.mnRow
= mxTable
->getRowCount() - 1;
578 case SID_TABLE_INSERT_ROW
:
580 TableModelNotifyGuard
aGuard( mxTable
.get() );
584 mpModel
->BegUndo( ImpGetResStr(STR_TABLE_INSROW
) );
585 mpModel
->AddUndo( mpModel
->GetSdrUndoFactory().CreateUndoGeoObject(*pTableObj
) );
588 Reference
< XTableRows
> xRows( mxTable
->getRows() );
589 const sal_Int32 nNewRows
= (nCount
== 0) ? (aEnd
.mnRow
- aStart
.mnRow
+ 1) : nCount
;
590 const sal_Int32 nNewRowStart
= aEnd
.mnRow
+ (bInsertAfter
? 1 : 0);
591 xRows
->insertByIndex( nNewRowStart
, nNewRows
);
593 for( sal_Int32 nOffset
= 0; nOffset
< nNewRows
; nOffset
++ )
595 Reference
< XPropertySet
>( xRows
->getByIndex( aEnd
.mnRow
+ nOffset
+ 1 ), UNO_QUERY_THROW
)->
596 setPropertyValue( sSize
,
597 Reference
< XPropertySet
>( xRows
->getByIndex( aStart
.mnRow
+ nOffset
), UNO_QUERY_THROW
)->
598 getPropertyValue( sSize
) );
605 aStart
.mnRow
= nNewRowStart
;
606 aEnd
.mnCol
= mxTable
->getColumnCount() - 1;
607 aEnd
.mnRow
= aStart
.mnRow
+ nNewRows
- 1;
612 StartSelection( aStart
);
613 UpdateSelection( aEnd
);
615 catch( Exception
& e
)
618 DBG_ERROR("svx::SvxTableController::onInsert(), exception caught!");
622 // --------------------------------------------------------------------
624 void SvxTableController::onDelete( sal_uInt16 nSId
)
626 ::sdr::table::SdrTableObj
* pTableObj
= dynamic_cast< ::sdr::table::SdrTableObj
* >( mxTableObj
.get() );
630 if( mxTable
.is() && hasSelectedCells() )
632 CellPos aStart
, aEnd
;
633 getSelectedCells( aStart
, aEnd
);
635 if( pTableObj
->IsTextEditActive() )
636 mpView
->SdrEndTextEdit(sal_True
);
640 bool bDeleteTable
= false;
643 case SID_TABLE_DELETE_COL
:
645 const sal_Int32 nRemovedColumns
= aEnd
.mnCol
- aStart
.mnCol
+ 1;
646 if( nRemovedColumns
== mxTable
->getColumnCount() )
652 Reference
< XTableColumns
> xCols( mxTable
->getColumns() );
653 xCols
->removeByIndex( aStart
.mnCol
, nRemovedColumns
);
658 case SID_TABLE_DELETE_ROW
:
660 const sal_Int32 nRemovedRows
= aEnd
.mnRow
- aStart
.mnRow
+ 1;
661 if( nRemovedRows
== mxTable
->getRowCount() )
667 Reference
< XTableRows
> xRows( mxTable
->getRows() );
668 xRows
->removeByIndex( aStart
.mnRow
, nRemovedRows
);
675 mpView
->DeleteMarkedObj();
681 // --------------------------------------------------------------------
683 void SvxTableController::onSelect( sal_uInt16 nSId
)
687 const sal_Int32 nRowCount
= mxTable
->getRowCount();
688 const sal_Int32 nColCount
= mxTable
->getColumnCount();
689 if( nRowCount
&& nColCount
)
691 CellPos aStart
, aEnd
;
692 getSelectedCells( aStart
, aEnd
);
696 case SID_TABLE_SELECT_ALL
:
697 aEnd
.mnCol
= 0; aEnd
.mnRow
= 0;
698 aStart
.mnCol
= nColCount
- 1; aStart
.mnRow
= nRowCount
- 1;
700 case SID_TABLE_SELECT_COL
:
701 aEnd
.mnRow
= nRowCount
- 1;
704 case SID_TABLE_SELECT_ROW
:
705 aEnd
.mnCol
= nColCount
- 1;
710 StartSelection( aEnd
);
711 gotoCell( aStart
, true, 0 );
716 // --------------------------------------------------------------------
717 void SvxTableController::onFormatTable( SfxRequest
& rReq
)
719 ::sdr::table::SdrTableObj
* pTableObj
= dynamic_cast< ::sdr::table::SdrTableObj
* >( mxTableObj
.get() );
723 const SfxItemSet
* pArgs
= rReq
.GetArgs();
725 if( !pArgs
&& pTableObj
->GetModel() )
727 SfxItemSet
aNewAttr( pTableObj
->GetModel()->GetItemPool() );
728 MergeAttrFromSelectedCells(aNewAttr
, FALSE
);
730 // merge drawing layer text distance items into SvxBoxItem used by the dialog
731 SvxBoxItem
aBoxItem( static_cast< const SvxBoxItem
& >( aNewAttr
.Get( SDRATTR_TABLE_BORDER
) ) );
732 aBoxItem
.SetDistance( sal::static_int_cast
< USHORT
>( ((SdrTextLeftDistItem
&)(aNewAttr
.Get(SDRATTR_TEXT_LEFTDIST
))).GetValue()), BOX_LINE_LEFT
);
733 aBoxItem
.SetDistance( sal::static_int_cast
< USHORT
>( ((SdrTextRightDistItem
&)(aNewAttr
.Get(SDRATTR_TEXT_RIGHTDIST
))).GetValue()), BOX_LINE_RIGHT
);
734 aBoxItem
.SetDistance( sal::static_int_cast
< USHORT
>( ((SdrTextUpperDistItem
&)(aNewAttr
.Get(SDRATTR_TEXT_UPPERDIST
))).GetValue()), BOX_LINE_TOP
);
735 aBoxItem
.SetDistance( sal::static_int_cast
< USHORT
>( ((SdrTextLowerDistItem
&)(aNewAttr
.Get(SDRATTR_TEXT_LOWERDIST
))).GetValue()), BOX_LINE_BOTTOM
);
736 aNewAttr
.Put( aBoxItem
);
738 SvxAbstractDialogFactory
* pFact
= SvxAbstractDialogFactory::Create();
739 std::auto_ptr
< SfxAbstractTabDialog
> pDlg( pFact
? pFact
->CreateSvxFormatCellsDialog( NULL
, &aNewAttr
, pTableObj
->GetModel(), pTableObj
) : 0 );
740 if( pDlg
.get() && pDlg
->Execute() )
742 SfxItemSet
aNewSet( *(pDlg
->GetOutputItemSet ()) );
744 SvxBoxItem
aNewBoxItem( static_cast< const SvxBoxItem
& >( aNewSet
.Get( SDRATTR_TABLE_BORDER
) ) );
746 if( aNewBoxItem
.GetDistance( BOX_LINE_LEFT
) != aBoxItem
.GetDistance( BOX_LINE_LEFT
) )
747 aNewSet
.Put(SdrTextLeftDistItem( aNewBoxItem
.GetDistance( BOX_LINE_LEFT
) ) );
749 if( aNewBoxItem
.GetDistance( BOX_LINE_RIGHT
) != aBoxItem
.GetDistance( BOX_LINE_RIGHT
) )
750 aNewSet
.Put(SdrTextRightDistItem( aNewBoxItem
.GetDistance( BOX_LINE_RIGHT
) ) );
752 if( aNewBoxItem
.GetDistance( BOX_LINE_TOP
) != aBoxItem
.GetDistance( BOX_LINE_TOP
) )
753 aNewSet
.Put(SdrTextUpperDistItem( aNewBoxItem
.GetDistance( BOX_LINE_TOP
) ) );
755 if( aNewBoxItem
.GetDistance( BOX_LINE_BOTTOM
) != aBoxItem
.GetDistance( BOX_LINE_BOTTOM
) )
756 aNewSet
.Put(SdrTextLowerDistItem( aNewBoxItem
.GetDistance( BOX_LINE_BOTTOM
) ) );
758 SetAttrToSelectedCells(aNewSet
, FALSE
);
764 // --------------------------------------------------------------------
766 void SvxTableController::Execute( SfxRequest
& rReq
)
768 const sal_uInt16 nSId
= rReq
.GetSlot();
771 case SID_TABLE_INSERT_ROW
:
772 case SID_TABLE_INSERT_COL
:
773 onInsert( nSId
, rReq
.GetArgs() );
775 case SID_TABLE_DELETE_ROW
:
776 case SID_TABLE_DELETE_COL
:
779 case SID_TABLE_SELECT_ALL
:
780 case SID_TABLE_SELECT_COL
:
781 case SID_TABLE_SELECT_ROW
:
784 case SID_FORMAT_TABLE_DLG
:
785 onFormatTable( rReq
);
788 case SID_FRAME_LINESTYLE
:
789 case SID_FRAME_LINECOLOR
:
790 case SID_ATTR_BORDER
:
792 const SfxItemSet
* pArgs
= rReq
.GetArgs();
794 ApplyBorderAttr( *pArgs
);
798 case SID_ATTR_FILL_STYLE
:
800 const SfxItemSet
* pArgs
= rReq
.GetArgs();
802 SetAttributes( *pArgs
, false );
806 case SID_TABLE_MERGE_CELLS
:
810 case SID_TABLE_SPLIT_CELLS
:
814 case SID_TABLE_DISTRIBUTE_COLUMNS
:
818 case SID_TABLE_DISTRIBUTE_ROWS
:
822 case SID_TABLE_VERT_BOTTOM
:
823 case SID_TABLE_VERT_CENTER
:
824 case SID_TABLE_VERT_NONE
:
829 case SID_TABLE_SORT_DIALOG
:
830 case SID_TABLE_AUTOSUM
:
834 case SID_TABLE_STYLE
:
835 SetTableStyle( rReq
.GetArgs() );
838 case SID_TABLE_STYLE_SETTINGS
:
839 SetTableStyleSettings( rReq
.GetArgs() );
844 void SvxTableController::SetTableStyle( const SfxItemSet
* pArgs
)
846 SdrTableObj
* pTableObj
= dynamic_cast< ::sdr::table::SdrTableObj
* >( mxTableObj
.get() );
847 SdrModel
* pModel
= pTableObj
? pTableObj
->GetModel() : 0;
849 if( !pTableObj
|| !pModel
|| !pArgs
|| (SFX_ITEM_SET
!= pArgs
->GetItemState(SID_TABLE_STYLE
, FALSE
)) )
852 const SfxStringItem
* pArg
= dynamic_cast< const SfxStringItem
* >( &pArgs
->Get( SID_TABLE_STYLE
) );
853 if( pArg
&& mxTable
.is() ) try
855 Reference
< XStyleFamiliesSupplier
> xSFS( pModel
->getUnoModel(), UNO_QUERY_THROW
);
856 Reference
< XNameAccess
> xFamilyNameAccess( xSFS
->getStyleFamilies(), UNO_QUERY_THROW
);
857 const OUString
sFamilyName( RTL_CONSTASCII_USTRINGPARAM( "table" ) );
858 Reference
< XNameAccess
> xTableFamilyAccess( xFamilyNameAccess
->getByName( sFamilyName
), UNO_QUERY_THROW
);
860 if( xTableFamilyAccess
->hasByName( pArg
->GetValue() ) )
862 // found table style with the same name
863 Reference
< XIndexAccess
> xNewTableStyle( xTableFamilyAccess
->getByName( pArg
->GetValue() ), UNO_QUERY_THROW
);
865 const bool bUndo
= pModel
->IsUndoEnabled();
869 pModel
->BegUndo( ImpGetResStr(STR_TABLE_STYLE
) );
870 pModel
->AddUndo( new TableStyleUndo( *pTableObj
) );
873 pTableObj
->setTableStyle( xNewTableStyle
);
875 const sal_Int32 nRowCount
= mxTable
->getRowCount();
876 const sal_Int32 nColCount
= mxTable
->getColumnCount();
877 for( sal_Int32 nRow
= 0; nRow
< nRowCount
; nRow
++ )
879 for( sal_Int32 nCol
= 0; nCol
< nColCount
; nCol
++ ) try
881 CellRef
xCell( dynamic_cast< Cell
* >( mxTable
->getCellByPosition( nCol
, nRow
).get() ) );
884 SfxItemSet
aSet( xCell
->GetItemSet() );
885 bool bChanges
= false;
886 const SfxItemSet
& rStyleAttribs
= xCell
->GetStyleSheet()->GetItemSet();
888 for ( USHORT nWhich
= SDRATTR_START
; nWhich
<= SDRATTR_TABLE_LAST
; nWhich
++ )
890 if( (rStyleAttribs
.GetItemState( nWhich
) == SFX_ITEM_ON
) && (aSet
.GetItemState( nWhich
) == SFX_ITEM_ON
) )
892 aSet
.ClearItem( nWhich
);
902 xCell
->SetMergedItemSetAndBroadcast( aSet
, sal_True
);
906 catch( Exception
& e
)
909 DBG_ERROR( "svx::SvxTableController::SetTableStyle(), exception caught!" );
917 catch( Exception
& e
)
920 DBG_ERROR( "svx::SvxTableController::SetTableStyle(), exception caught!" );
924 void SvxTableController::SetTableStyleSettings( const SfxItemSet
* pArgs
)
926 SdrTableObj
* pTableObj
= dynamic_cast< ::sdr::table::SdrTableObj
* >( mxTableObj
.get() );
927 SdrModel
* pModel
= pTableObj
? pTableObj
->GetModel() : 0;
929 if( !pTableObj
|| !pModel
)
932 TableStyleSettings
aSettings( pTableObj
->getTableStyleSettings() );
934 const SfxPoolItem
*pPoolItem
=NULL
;
936 if( (SFX_ITEM_SET
== pArgs
->GetItemState(ID_VAL_USEFIRSTROWSTYLE
, FALSE
,&pPoolItem
)) )
937 aSettings
.mbUseFirstRow
= static_cast< const SfxBoolItem
* >(pPoolItem
)->GetValue();
939 if( (SFX_ITEM_SET
== pArgs
->GetItemState(ID_VAL_USELASTROWSTYLE
, FALSE
,&pPoolItem
)) )
940 aSettings
.mbUseLastRow
= static_cast< const SfxBoolItem
* >(pPoolItem
)->GetValue();
942 if( (SFX_ITEM_SET
== pArgs
->GetItemState(ID_VAL_USEBANDINGROWSTYLE
, FALSE
,&pPoolItem
)) )
943 aSettings
.mbUseRowBanding
= static_cast< const SfxBoolItem
* >(pPoolItem
)->GetValue();
945 if( (SFX_ITEM_SET
== pArgs
->GetItemState(ID_VAL_USEFIRSTCOLUMNSTYLE
, FALSE
,&pPoolItem
)) )
946 aSettings
.mbUseFirstColumn
= static_cast< const SfxBoolItem
* >(pPoolItem
)->GetValue();
948 if( (SFX_ITEM_SET
== pArgs
->GetItemState(ID_VAL_USELASTCOLUMNSTYLE
, FALSE
,&pPoolItem
)) )
949 aSettings
.mbUseLastColumn
= static_cast< const SfxBoolItem
* >(pPoolItem
)->GetValue();
951 if( (SFX_ITEM_SET
== pArgs
->GetItemState(ID_VAL_USEBANDINGCOLUMNSTYLE
, FALSE
,&pPoolItem
)) )
952 aSettings
.mbUseColumnBanding
= static_cast< const SfxBoolItem
* >(pPoolItem
)->GetValue();
954 if( aSettings
== pTableObj
->getTableStyleSettings() )
957 const bool bUndo
= pModel
->IsUndoEnabled();
961 pModel
->BegUndo( ImpGetResStr(STR_TABLE_STYLE_SETTINGS
) );
962 pModel
->AddUndo( new TableStyleUndo( *pTableObj
) );
965 pTableObj
->setTableStyleSettings( aSettings
);
971 void SvxTableController::SetVertical( sal_uInt16 nSId
)
973 SdrTableObj
* pTableObj
= dynamic_cast< ::sdr::table::SdrTableObj
* >( mxTableObj
.get() );
974 if( mxTable
.is() && pTableObj
)
976 TableModelNotifyGuard
aGuard( mxTable
.get() );
978 CellPos aStart
, aEnd
;
979 getSelectedCells( aStart
, aEnd
);
981 SdrTextVertAdjust eAdj
= SDRTEXTVERTADJUST_TOP
;
985 case SID_TABLE_VERT_BOTTOM
:
986 eAdj
= SDRTEXTVERTADJUST_BOTTOM
;
988 case SID_TABLE_VERT_CENTER
:
989 eAdj
= SDRTEXTVERTADJUST_CENTER
;
991 //case SID_TABLE_VERT_NONE:
996 SdrTextVertAdjustItem
aItem( eAdj
);
998 for( sal_Int32 nRow
= aStart
.mnRow
; nRow
<= aEnd
.mnRow
; nRow
++ )
1000 for( sal_Int32 nCol
= aStart
.mnCol
; nCol
<= aEnd
.mnCol
; nCol
++ )
1002 CellRef
xCell( dynamic_cast< Cell
* >( mxTable
->getCellByPosition( nCol
, nRow
).get() ) );
1004 xCell
->SetMergedItem(aItem
);
1012 void SvxTableController::MergeMarkedCells()
1014 CellPos aStart
, aEnd
;
1015 getSelectedCells( aStart
, aEnd
);
1016 SdrTableObj
* pTableObj
= dynamic_cast< ::sdr::table::SdrTableObj
* >( mxTableObj
.get() );
1019 if( pTableObj
->IsTextEditActive() )
1020 mpView
->SdrEndTextEdit(sal_True
);
1022 TableModelNotifyGuard
aGuard( mxTable
.get() );
1023 MergeRange( aStart
.mnCol
, aStart
.mnRow
, aEnd
.mnCol
, aEnd
.mnRow
);
1027 void SvxTableController::SplitMarkedCells()
1031 CellPos aStart
, aEnd
;
1032 getSelectedCells( aStart
, aEnd
);
1034 SvxAbstractDialogFactory
* pFact
= SvxAbstractDialogFactory::Create();
1035 std::auto_ptr
< SvxAbstractSplittTableDialog
> xDlg( pFact
? pFact
->CreateSvxSplittTableDialog( NULL
, false, 99, 99 ) : 0 );
1036 if( xDlg
.get() && xDlg
->Execute() )
1038 const sal_Int32 nCount
= xDlg
->GetCount() - 1;
1042 getSelectedCells( aStart
, aEnd
);
1044 Reference
< XMergeableCellRange
> xRange( mxTable
->createCursorByRange( mxTable
->getCellRangeByPosition( aStart
.mnCol
, aStart
.mnRow
, aEnd
.mnCol
, aEnd
.mnRow
) ), UNO_QUERY_THROW
);
1046 const sal_Int32 nRowCount
= mxTable
->getRowCount();
1047 const sal_Int32 nColCount
= mxTable
->getColumnCount();
1050 SdrTableObj
* pTableObj
= dynamic_cast< SdrTableObj
* >( mxTableObj
.get() );
1053 if( pTableObj
->IsTextEditActive() )
1054 mpView
->SdrEndTextEdit(sal_True
);
1056 TableModelNotifyGuard
aGuard( mxTable
.get() );
1058 const bool bUndo
= mpModel
&& mpModel
->IsUndoEnabled();
1061 mpModel
->BegUndo( ImpGetResStr(STR_TABLE_SPLIT
) );
1062 mpModel
->AddUndo( mpModel
->GetSdrUndoFactory().CreateUndoGeoObject(*pTableObj
) );
1065 if( xDlg
->IsHorizontal() )
1067 xRange
->split( 0, nCount
);
1071 xRange
->split( nCount
, 0 );
1077 aEnd
.mnRow
+= mxTable
->getRowCount() - nRowCount
;
1078 aEnd
.mnCol
+= mxTable
->getColumnCount() - nColCount
;
1080 setSelectedCells( aStart
, aEnd
);
1085 void SvxTableController::DistributeColumns()
1087 SdrTableObj
* pTableObj
= dynamic_cast< SdrTableObj
* >( mxTableObj
.get() );
1090 const bool bUndo
= mpModel
&& mpModel
->IsUndoEnabled();
1093 mpModel
->BegUndo( ImpGetResStr(STR_TABLE_DISTRIBUTE_COLUMNS
) );
1094 mpModel
->AddUndo( mpModel
->GetSdrUndoFactory().CreateUndoGeoObject(*pTableObj
) );
1097 CellPos aStart
, aEnd
;
1098 getSelectedCells( aStart
, aEnd
);
1099 pTableObj
->DistributeColumns( aStart
.mnCol
, aEnd
.mnCol
);
1106 void SvxTableController::DistributeRows()
1108 SdrTableObj
* pTableObj
= dynamic_cast< SdrTableObj
* >( mxTableObj
.get() );
1111 const bool bUndo
= mpModel
&& mpModel
->IsUndoEnabled();
1114 mpModel
->BegUndo( ImpGetResStr(STR_TABLE_DISTRIBUTE_ROWS
) );
1115 mpModel
->AddUndo( mpModel
->GetSdrUndoFactory().CreateUndoGeoObject(*pTableObj
) );
1118 CellPos aStart
, aEnd
;
1119 getSelectedCells( aStart
, aEnd
);
1120 pTableObj
->DistributeRows( aStart
.mnRow
, aEnd
.mnRow
);
1127 bool SvxTableController::DeleteMarked()
1129 if( mbCellSelectionMode
)
1133 CellPos aStart
, aEnd
;
1134 getSelectedCells( aStart
, aEnd
);
1135 for( sal_Int32 nRow
= aStart
.mnRow
; nRow
<= aEnd
.mnRow
; nRow
++ )
1137 for( sal_Int32 nCol
= aStart
.mnCol
; nCol
<= aEnd
.mnCol
; nCol
++ )
1139 CellRef
xCell( dynamic_cast< Cell
* >( mxTable
->getCellByPosition( nCol
, nRow
).get() ) );
1141 xCell
->SetOutlinerParaObject( 0 );
1153 bool SvxTableController::GetStyleSheet( SfxStyleSheet
*& rpStyleSheet
) const
1155 if( hasSelectedCells() )
1161 SfxStyleSheet
* pRet
=0;
1164 CellPos aStart
, aEnd
;
1165 const_cast<SvxTableController
&>(*this).getSelectedCells( aStart
, aEnd
);
1167 for( sal_Int32 nRow
= aStart
.mnRow
; nRow
<= aEnd
.mnRow
; nRow
++ )
1169 for( sal_Int32 nCol
= aStart
.mnCol
; nCol
<= aEnd
.mnCol
; nCol
++ )
1171 CellRef
xCell( dynamic_cast< Cell
* >( mxTable
->getCellByPosition( nCol
, nRow
).get() ) );
1174 SfxStyleSheet
* pSS
=xCell
->GetStyleSheet();
1179 else if(pRet
!= pSS
)
1187 rpStyleSheet
= pRet
;
1194 bool SvxTableController::SetStyleSheet( SfxStyleSheet
* pStyleSheet
, bool bDontRemoveHardAttr
)
1196 if( hasSelectedCells() && (!pStyleSheet
|| pStyleSheet
->GetFamily() == SFX_STYLE_FAMILY_FRAME
) )
1200 CellPos aStart
, aEnd
;
1201 getSelectedCells( aStart
, aEnd
);
1203 for( sal_Int32 nRow
= aStart
.mnRow
; nRow
<= aEnd
.mnRow
; nRow
++ )
1205 for( sal_Int32 nCol
= aStart
.mnCol
; nCol
<= aEnd
.mnCol
; nCol
++ )
1207 CellRef
xCell( dynamic_cast< Cell
* >( mxTable
->getCellByPosition( nCol
, nRow
).get() ) );
1209 xCell
->SetStyleSheet(pStyleSheet
,bDontRemoveHardAttr
);
1220 // --------------------------------------------------------------------
1222 // --------------------------------------------------------------------
1224 bool SvxTableController::checkTableObject()
1226 return mxTableObj
.is();
1229 // --------------------------------------------------------------------
1231 sal_uInt16
SvxTableController::getKeyboardAction( const KeyEvent
& rKEvt
, Window
* /*pWindow*/ )
1233 const bool bMod1
= rKEvt
.GetKeyCode().IsMod1(); // ctrl
1234 const bool bMod2
= rKEvt
.GetKeyCode().IsMod2() != 0; // Alt
1236 const bool bTextEdit
= mpView
->IsTextEdit();
1238 sal_uInt16 nAction
= ACTION_HANDLED_BY_VIEW
;
1240 ::sdr::table::SdrTableObj
* pTableObj
= dynamic_cast< ::sdr::table::SdrTableObj
* >( mxTableObj
.get() );
1244 // handle special keys
1245 const sal_Int16 nCode
= rKEvt
.GetKeyCode().GetCode();
1248 case awt::Key::ESCAPE
: // handle escape
1252 // escape during text edit ends text edit
1253 nAction
= ACTION_STOP_TEXT_EDIT
;
1255 if( mbCellSelectionMode
)
1257 // escape with selected cells removes selection
1258 nAction
= ACTION_REMOVE_SELECTION
;
1262 case awt::Key::RETURN
: // handle return
1264 if( !bMod1
&& !bMod2
&& !bTextEdit
)
1266 // when not already editing, return starts text edit
1267 setSelectionStart( pTableObj
->getFirstCell() );
1268 nAction
= ACTION_EDIT_CELL
;
1272 case awt::Key::F2
: // f2 toggles text edit
1274 if( bMod1
|| bMod2
) // f2 with modifiers is handled by the view
1277 else if( bTextEdit
)
1279 // f2 during text edit stops text edit
1280 nAction
= ACTION_STOP_TEXT_EDIT
;
1282 else if( mbCellSelectionMode
)
1284 // f2 with selected cells removes selection
1285 nAction
= ACTION_REMOVE_SELECTION
;
1289 // f2 with no selection and no text edit starts text edit
1290 setSelectionStart( pTableObj
->getFirstCell() );
1291 nAction
= ACTION_EDIT_CELL
;
1295 case awt::Key::HOME
:
1296 case awt::Key::NUM7
:
1298 if( (bMod1
|| bMod2
) && (bTextEdit
|| mbCellSelectionMode
) )
1300 if( bMod1
&& !bMod2
)
1302 // strg + home jumps to first cell
1303 nAction
= ACTION_GOTO_FIRST_CELL
;
1305 else if( !bMod1
&& bMod2
)
1307 // alt + home jumps to first column
1308 nAction
= ACTION_GOTO_FIRST_COLUMN
;
1314 case awt::Key::NUM1
:
1316 if( (bMod1
|| bMod2
) && (bTextEdit
|| mbCellSelectionMode
) )
1318 if( bMod1
&& !bMod2
)
1320 // strg + end jumps to last cell
1321 nAction
= ACTION_GOTO_LAST_CELL
;
1323 else if( !bMod1
&& bMod2
)
1325 // alt + home jumps to last column
1326 nAction
= ACTION_GOTO_LAST_COLUMN
;
1334 if( bTextEdit
|| mbCellSelectionMode
)
1335 nAction
= ACTION_TAB
;
1340 case awt::Key::NUM8
:
1341 case awt::Key::DOWN
:
1342 case awt::Key::NUM2
:
1343 case awt::Key::LEFT
:
1344 case awt::Key::NUM4
:
1345 case awt::Key::RIGHT
:
1346 case awt::Key::NUM6
:
1348 bool bTextMove
= false;
1350 if( !bMod1
&& bMod2
)
1352 if( (nCode
== awt::Key::UP
) || (nCode
== awt::Key::NUM8
) )
1354 nAction
= ACTION_GOTO_LEFT_CELL
;
1356 else if( (nCode
== awt::Key::DOWN
) || (nCode
== awt::Key::NUM2
) )
1358 nAction
= ACTION_GOTO_RIGHT_CELL
;
1365 OutlinerView
* pOLV
= mpView
->GetTextEditOutlinerView();
1369 // during text edit, check if we navigate out of the cell
1370 ESelection aOldSelection
= pOLV
->GetSelection();
1371 pOLV
->PostKeyEvent(rKEvt
);
1372 bTextMove
= pOLV
&& ( aOldSelection
.IsEqual(pOLV
->GetSelection()) );
1375 nAction
= ACTION_NONE
;
1380 if( mbCellSelectionMode
|| bTextMove
)
1382 // no text edit, navigate in cells if selection active
1385 case awt::Key::LEFT
:
1386 case awt::Key::NUM4
:
1387 nAction
= ACTION_GOTO_LEFT_CELL
;
1389 case awt::Key::RIGHT
:
1390 case awt::Key::NUM6
:
1391 nAction
= ACTION_GOTO_RIGHT_CELL
;
1393 case awt::Key::DOWN
:
1394 case awt::Key::NUM2
:
1395 nAction
= ACTION_GOTO_DOWN_CELL
;
1398 case awt::Key::NUM8
:
1399 nAction
= ACTION_GOTO_UP_CELL
;
1405 case awt::Key::PAGEUP
:
1407 nAction
= ACTION_GOTO_FIRST_ROW
;
1410 case awt::Key::PAGEDOWN
:
1412 nAction
= ACTION_GOTO_LAST_ROW
;
1418 bool SvxTableController::executeAction( sal_uInt16 nAction
, bool bSelect
, Window
* pWindow
)
1420 ::sdr::table::SdrTableObj
* pTableObj
= dynamic_cast< ::sdr::table::SdrTableObj
* >( mxTableObj
.get() );
1426 case ACTION_GOTO_FIRST_CELL
:
1428 gotoCell( pTableObj
->getFirstCell(), bSelect
, pWindow
, nAction
);
1432 case ACTION_GOTO_LEFT_CELL
:
1434 gotoCell( pTableObj
->getLeftCell( getSelectionEnd(), !bSelect
), bSelect
, pWindow
, nAction
);
1438 case ACTION_GOTO_RIGHT_CELL
:
1440 gotoCell( pTableObj
->getRightCell( getSelectionEnd(), !bSelect
), bSelect
, pWindow
, nAction
);
1444 case ACTION_GOTO_LAST_CELL
:
1446 gotoCell( pTableObj
->getLastCell(), bSelect
, pWindow
, nAction
);
1450 case ACTION_GOTO_FIRST_COLUMN
:
1452 CellPos
aPos( pTableObj
->getFirstCell().mnCol
, getSelectionEnd().mnRow
);
1453 gotoCell( aPos
, bSelect
, pWindow
, nAction
);
1457 case ACTION_GOTO_LAST_COLUMN
:
1459 CellPos
aPos( pTableObj
->getLastCell().mnCol
, getSelectionEnd().mnRow
);
1460 gotoCell( aPos
, bSelect
, pWindow
, nAction
);
1464 case ACTION_GOTO_FIRST_ROW
:
1466 CellPos
aPos( getSelectionEnd().mnCol
, pTableObj
->getFirstCell().mnRow
);
1467 gotoCell( aPos
, bSelect
, pWindow
, nAction
);
1471 case ACTION_GOTO_UP_CELL
:
1473 gotoCell( pTableObj
->getUpCell(getSelectionEnd(), !bSelect
), bSelect
, pWindow
, nAction
);
1477 case ACTION_GOTO_DOWN_CELL
:
1479 gotoCell( pTableObj
->getDownCell(getSelectionEnd(), !bSelect
), bSelect
, pWindow
, nAction
);
1483 case ACTION_GOTO_LAST_ROW
:
1485 CellPos
aPos( getSelectionEnd().mnCol
, pTableObj
->getLastCell().mnRow
);
1486 gotoCell( aPos
, bSelect
, pWindow
, nAction
);
1490 case ACTION_EDIT_CELL
:
1491 EditCell( getSelectionStart(), pWindow
, 0, nAction
);
1494 case ACTION_STOP_TEXT_EDIT
:
1498 case ACTION_REMOVE_SELECTION
:
1502 case ACTION_START_SELECTION
:
1503 StartSelection( getSelectionStart() );
1509 gotoCell( pTableObj
->getPreviousCell( getSelectionEnd(), true ), false, pWindow
, nAction
);
1512 CellPos
aSelectionEnd( getSelectionEnd() );
1513 CellPos
aNextCell( pTableObj
->getNextCell( aSelectionEnd
, true ) );
1514 if( aSelectionEnd
== aNextCell
)
1516 onInsert( SID_TABLE_INSERT_ROW
, 0 );
1517 aNextCell
= pTableObj
->getNextCell( aSelectionEnd
, true );
1519 gotoCell( aNextCell
, false, pWindow
, nAction
);
1525 return nAction
!= ACTION_HANDLED_BY_VIEW
;
1528 // --------------------------------------------------------------------
1530 void SvxTableController::gotoCell( const CellPos
& rPos
, bool bSelect
, Window
* pWindow
, sal_uInt16 nAction
)
1532 if( mxTableObj
.is() && static_cast<SdrTableObj
*>(mxTableObj
.get())->IsTextEditActive() )
1533 mpView
->SdrEndTextEdit(sal_True
);
1537 maCursorLastPos
= rPos
;
1538 if( mxTableObj
.is() )
1539 static_cast< SdrTableObj
* >( mxTableObj
.get() )->setActiveCell( rPos
);
1541 if( !mbCellSelectionMode
)
1543 setSelectedCells( maCursorFirstPos
, rPos
);
1547 UpdateSelection( rPos
);
1553 EditCell( rPos
, pWindow
, 0, nAction
);
1557 // --------------------------------------------------------------------
1559 const CellPos
& SvxTableController::getSelectionStart()
1561 checkCell( maCursorFirstPos
);
1562 return maCursorFirstPos
;
1565 // --------------------------------------------------------------------
1567 void SvxTableController::setSelectionStart( const CellPos
& rPos
)
1569 maCursorFirstPos
= rPos
;
1572 // --------------------------------------------------------------------
1574 const CellPos
& SvxTableController::getSelectionEnd()
1576 checkCell( maCursorLastPos
);
1577 return maCursorLastPos
;
1580 // --------------------------------------------------------------------
1582 Reference
< XCellCursor
> SvxTableController::getSelectionCursor()
1584 Reference
< XCellCursor
> xCursor
;
1588 if( hasSelectedCells() )
1590 CellPos aStart
, aEnd
;
1591 getSelectedCells( aStart
, aEnd
);
1592 xCursor
= mxTable
->createCursorByRange( mxTable
->getCellRangeByPosition( aStart
.mnCol
, aStart
.mnRow
, aEnd
.mnCol
, aEnd
.mnRow
) );
1596 xCursor
= mxTable
->createCursor();
1603 void SvxTableController::MergeRange( sal_Int32 nFirstCol
, sal_Int32 nFirstRow
, sal_Int32 nLastCol
, sal_Int32 nLastRow
)
1605 if( mxTable
.is() ) try
1607 Reference
< XMergeableCellRange
> xRange( mxTable
->createCursorByRange( mxTable
->getCellRangeByPosition( nFirstCol
, nFirstRow
,nLastCol
, nLastRow
) ), UNO_QUERY_THROW
);
1608 if( xRange
->isMergeable() )
1610 const bool bUndo
= mpModel
&& mpModel
->IsUndoEnabled();
1613 mpModel
->BegUndo( ImpGetResStr(STR_TABLE_MERGE
) );
1614 mpModel
->AddUndo( mpModel
->GetSdrUndoFactory().CreateUndoGeoObject(*mxTableObj
.get()) );
1625 DBG_ASSERT( false, "sdr::table::SvxTableController::MergeRange(), exception caught!" );
1631 // --------------------------------------------------------------------
1633 void SvxTableController::checkCell( CellPos
& rPos
)
1635 if( mxTable
.is() ) try
1637 if( rPos
.mnCol
>= mxTable
->getColumnCount() )
1638 rPos
.mnCol
= mxTable
->getColumnCount()-1;
1640 if( rPos
.mnRow
>= mxTable
->getRowCount() )
1641 rPos
.mnRow
= mxTable
->getRowCount()-1;
1643 catch( Exception
& e
)
1646 DBG_ERROR("sdr::table::SvxTableController::checkCell(), exception caught!" );
1650 // --------------------------------------------------------------------
1652 void SvxTableController::findMergeOrigin( CellPos
& rPos
)
1654 if( mxTable
.is() ) try
1656 Reference
< XMergeableCell
> xCell( mxTable
->getCellByPosition( rPos
.mnCol
, rPos
.mnRow
), UNO_QUERY_THROW
);
1657 if( xCell
.is() && xCell
->isMerged() )
1659 ::findMergeOrigin( mxTable
, rPos
.mnCol
, rPos
.mnRow
, rPos
.mnCol
, rPos
.mnRow
);
1662 catch( Exception
& e
)
1665 DBG_ERROR("sdr::table::SvxTableController::findMergeOrigin(), exception caught!" );
1669 // --------------------------------------------------------------------
1671 void SvxTableController::EditCell( const CellPos
& rPos
, ::Window
* pWindow
, const awt::MouseEvent
* pMouseEvent
/*= 0*/, sal_uInt16 nAction
/*= ACTION_NONE */ )
1673 SdrPageView
* pPV
= mpView
->GetSdrPageView();
1675 ::sdr::table::SdrTableObj
* pTableObj
= dynamic_cast< ::sdr::table::SdrTableObj
* >( mxTableObj
.get() );
1676 if( pTableObj
&& pTableObj
->GetPage() == pPV
->GetPage() )
1678 bool bEmptyOutliner
= false;
1680 if(!pTableObj
->GetOutlinerParaObject() && mpView
->GetTextEditOutliner())
1682 ::Outliner
* pOutl
= mpView
->GetTextEditOutliner();
1683 ULONG nParaAnz
= pOutl
->GetParagraphCount();
1684 Paragraph
* p1stPara
= pOutl
->GetParagraph( 0 );
1686 if(nParaAnz
==1 && p1stPara
)
1688 // Bei nur einem Pararaph
1689 if (pOutl
->GetText(p1stPara
).Len() == 0)
1691 bEmptyOutliner
= true;
1696 CellPos
aPos( rPos
);
1697 findMergeOrigin( aPos
);
1699 if( pTableObj
!= mpView
->GetTextEditObject() || bEmptyOutliner
|| !pTableObj
->IsTextEditActive( aPos
) )
1701 if( pTableObj
->IsTextEditActive() )
1702 mpView
->SdrEndTextEdit(sal_True
);
1704 pTableObj
->setActiveCell( aPos
);
1706 // create new outliner, owner will be the SdrObjEditView
1707 SdrOutliner
* pOutl
= SdrMakeOutliner( OUTLINERMODE_OUTLINEOBJECT
, mpModel
);
1708 if( pTableObj
->IsVerticalWriting() )
1709 pOutl
->SetVertical( TRUE
);
1711 if(mpView
->SdrBeginTextEdit(pTableObj
, pPV
, pWindow
, sal_True
, pOutl
))
1713 maCursorLastPos
= maCursorFirstPos
= rPos
;
1715 OutlinerView
* pOLV
= mpView
->GetTextEditOutlinerView();
1721 ::MouseEvent
aMEvt( *pMouseEvent
);
1724 SdrHitKind eHit
= mpView
->PickAnything(aMEvt
, SDRMOUSEBUTTONDOWN
, aVEvt
);
1726 if (eHit
== SDRHIT_TEXTEDIT
)
1729 pOLV
->MouseButtonDown(aMEvt
);
1730 pOLV
->MouseMove(aMEvt
);
1731 pOLV
->MouseButtonUp(aMEvt
);
1732 // pOLV->MouseButtonDown(aMEvt);
1737 nAction
= ACTION_GOTO_LEFT_CELL
;
1743 // Move cursor to end of text
1744 ESelection aNewSelection
;
1746 const WritingMode eMode
= pTableObj
->GetWritingMode();
1747 if( ((nAction
== ACTION_GOTO_LEFT_CELL
) || (nAction
== ACTION_GOTO_RIGHT_CELL
)) && (eMode
!= WritingMode_TB_RL
) )
1749 const bool bLast
= ((nAction
== ACTION_GOTO_LEFT_CELL
) && (eMode
== WritingMode_LR_TB
)) ||
1750 ((nAction
== ACTION_GOTO_RIGHT_CELL
) && (eMode
== WritingMode_RL_TB
));
1753 aNewSelection
= ESelection(EE_PARA_NOT_FOUND
, EE_INDEX_NOT_FOUND
, EE_PARA_NOT_FOUND
, EE_INDEX_NOT_FOUND
);
1755 pOLV
->SetSelection(aNewSelection
);
1762 // --------------------------------------------------------------------
1764 bool SvxTableController::StopTextEdit()
1766 if(mpView
->IsTextEdit())
1768 mpView
->SdrEndTextEdit();
1769 mpView
->SetCurrentObj(OBJ_TABLE
);
1770 mpView
->SetEditMode(SDREDITMODE_EDIT
);
1779 // --------------------------------------------------------------------
1781 void SvxTableController::DeleteTable()
1786 // --------------------------------------------------------------------
1788 void SvxTableController::getSelectedCells( CellPos
& rFirst
, CellPos
& rLast
)
1790 if( mbCellSelectionMode
)
1792 checkCell( maCursorFirstPos
);
1793 checkCell( maCursorLastPos
);
1795 rFirst
.mnCol
= std::min( maCursorFirstPos
.mnCol
, maCursorLastPos
.mnCol
);
1796 rFirst
.mnRow
= std::min( maCursorFirstPos
.mnRow
, maCursorLastPos
.mnRow
);
1797 rLast
.mnCol
= std::max( maCursorFirstPos
.mnCol
, maCursorLastPos
.mnCol
);
1798 rLast
.mnRow
= std::max( maCursorFirstPos
.mnRow
, maCursorLastPos
.mnRow
);
1801 if( mxTable
.is() ) do
1804 for( sal_Int32 nRow
= rFirst
.mnRow
; nRow
<= rLast
.mnRow
&& !bExt
; nRow
++ )
1806 for( sal_Int32 nCol
= rFirst
.mnCol
; nCol
<= rLast
.mnCol
&& !bExt
; nCol
++ )
1808 Reference
< XMergeableCell
> xCell( mxTable
->getCellByPosition( nCol
, nRow
), UNO_QUERY
);
1812 if( xCell
->isMerged() )
1814 CellPos
aPos( nCol
, nRow
);
1815 findMergeOrigin( aPos
);
1816 if( (aPos
.mnCol
< rFirst
.mnCol
) || (aPos
.mnRow
< rFirst
.mnRow
) )
1818 rFirst
.mnCol
= std::min( rFirst
.mnCol
, aPos
.mnCol
);
1819 rFirst
.mnRow
= std::min( rFirst
.mnRow
, aPos
.mnRow
);
1825 if( ((nCol
+ xCell
->getColumnSpan() - 1) > rLast
.mnCol
) || (nRow
+ xCell
->getRowSpan() - 1 ) > rLast
.mnRow
)
1827 rLast
.mnCol
= std::max( rLast
.mnCol
, nCol
+ xCell
->getColumnSpan() - 1 );
1828 rLast
.mnRow
= std::max( rLast
.mnRow
, nRow
+ xCell
->getRowSpan() - 1 );
1837 else if( mpView
&& mpView
->IsTextEdit() )
1839 rFirst
= getSelectionStart();
1840 findMergeOrigin( rFirst
);
1845 Reference
< XMergeableCell
> xCell( mxTable
->getCellByPosition( rLast
.mnCol
, rLast
.mnRow
), UNO_QUERY
);
1848 rLast
.mnCol
+= xCell
->getColumnSpan() - 1;
1849 rLast
.mnRow
+= xCell
->getRowSpan() - 1;
1859 rLast
.mnRow
= mxTable
->getRowCount()-1;
1860 rLast
.mnCol
= mxTable
->getColumnCount()-1;
1870 // --------------------------------------------------------------------
1872 void SvxTableController::StartSelection( const CellPos
& rPos
)
1875 mbCellSelectionMode
= true;
1876 maCursorLastPos
= maCursorFirstPos
= rPos
;
1877 mpView
->MarkListHasChanged();
1880 // --------------------------------------------------------------------
1882 void SvxTableController::setSelectedCells( const CellPos
& rStart
, const CellPos
& rEnd
)
1885 mbCellSelectionMode
= true;
1886 maCursorFirstPos
= rStart
;
1887 UpdateSelection( rEnd
);
1890 // --------------------------------------------------------------------
1892 void SvxTableController::UpdateSelection( const CellPos
& rPos
)
1894 maCursorLastPos
= rPos
;
1895 mpView
->MarkListHasChanged();
1898 // --------------------------------------------------------------------
1900 void SvxTableController::clearSelection()
1905 // --------------------------------------------------------------------
1907 void SvxTableController::selectAll()
1911 CellPos aPos1
, aPos2( mxTable
->getColumnCount()-1, mxTable
->getRowCount()-1 );
1912 if( (aPos2
.mnCol
>= 0) && (aPos2
.mnRow
>= 0) )
1914 setSelectedCells( aPos1
, aPos2
);
1919 // --------------------------------------------------------------------
1921 void SvxTableController::RemoveSelection()
1923 if( mbCellSelectionMode
)
1925 mbCellSelectionMode
= false;
1926 mpView
->MarkListHasChanged();
1930 // --------------------------------------------------------------------
1932 void SvxTableController::onTableModified()
1934 if( mnUpdateEvent
== 0 )
1935 mnUpdateEvent
= Application::PostUserEvent( LINK( this, SvxTableController
, UpdateHdl
) );
1937 // --------------------------------------------------------------------
1939 void SvxTableController::updateSelectionOverlay()
1941 destroySelectionOverlay();
1942 if( mbCellSelectionMode
)
1944 ::sdr::table::SdrTableObj
* pTableObj
= dynamic_cast< ::sdr::table::SdrTableObj
* >( mxTableObj
.get() );
1947 sdr::overlay::OverlayObjectCell::RangeVector aRanges
;
1950 CellPos aStart
,aEnd
;
1951 getSelectedCells( aStart
, aEnd
);
1952 pTableObj
->getCellBounds( aStart
, aRect
);
1954 basegfx::B2DRange
a2DRange( basegfx::B2DPoint(aRect
.Left(), aRect
.Top()) );
1955 a2DRange
.expand( basegfx::B2DPoint(aRect
.Right(), aRect
.Bottom()) );
1957 findMergeOrigin( aEnd
);
1958 pTableObj
->getCellBounds( aEnd
, aRect
);
1959 a2DRange
.expand( basegfx::B2DPoint(aRect
.Left(), aRect
.Top()) );
1960 a2DRange
.expand( basegfx::B2DPoint(aRect
.Right(), aRect
.Bottom()) );
1961 aRanges
.push_back( a2DRange
);
1963 ::Color
aHighlight( COL_BLUE
);
1964 OutputDevice
* pOutDev
= mpView
->GetFirstOutputDevice();
1966 aHighlight
= pOutDev
->GetSettings().GetStyleSettings().GetHighlightColor();
1968 const sal_uInt32 nCount
= mpView
->PaintWindowCount();
1969 for( sal_uInt32 nIndex
= 0; nIndex
< nCount
; nIndex
++ )
1971 SdrPaintWindow
* pPaintWindow
= mpView
->GetPaintWindow(nIndex
);
1974 ::sdr::overlay::OverlayManager
* pOverlayManager
= pPaintWindow
->GetOverlayManager();
1975 if( pOverlayManager
)
1977 // sdr::overlay::CellOverlayType eType = sdr::overlay::CELL_OVERLAY_INVERT;
1978 sdr::overlay::CellOverlayType eType
= sdr::overlay::CELL_OVERLAY_TRANSPARENT
;
1980 sdr::overlay::OverlayObjectCell
* pOverlay
= new sdr::overlay::OverlayObjectCell( eType
, aHighlight
, aRanges
);
1982 pOverlayManager
->add(*pOverlay
);
1983 mpSelectionOverlay
= new ::sdr::overlay::OverlayObjectList
;
1984 mpSelectionOverlay
->append(*pOverlay
);
1992 // --------------------------------------------------------------------
1994 void SvxTableController::destroySelectionOverlay()
1996 if( mpSelectionOverlay
)
1998 delete mpSelectionOverlay
;
1999 mpSelectionOverlay
= 0;
2003 // --------------------------------------------------------------------
2005 void SvxTableController::MergeAttrFromSelectedCells(SfxItemSet
& rAttr
, bool bOnlyHardAttr
) const
2009 CellPos aStart
, aEnd
;
2010 const_cast<SvxTableController
&>(*this).getSelectedCells( aStart
, aEnd
);
2012 for( sal_Int32 nRow
= aStart
.mnRow
; nRow
<= aEnd
.mnRow
; nRow
++ )
2014 for( sal_Int32 nCol
= aStart
.mnCol
; nCol
<= aEnd
.mnCol
; nCol
++ )
2016 CellRef
xCell( dynamic_cast< Cell
* >( mxTable
->getCellByPosition( nCol
, nRow
).get() ) );
2017 if( xCell
.is() && !xCell
->isMerged() )
2019 const SfxItemSet
& rSet
= xCell
->GetItemSet();
2020 SfxWhichIter
aIter(rSet
);
2021 sal_uInt16
nWhich(aIter
.FirstWhich());
2026 if(SFX_ITEM_DONTCARE
== rSet
.GetItemState(nWhich
, FALSE
))
2027 rAttr
.InvalidateItem(nWhich
);
2029 rAttr
.MergeValue(rSet
.Get(nWhich
), TRUE
);
2031 else if(SFX_ITEM_SET
== rSet
.GetItemState(nWhich
, FALSE
))
2033 const SfxPoolItem
& rItem
= rSet
.Get(nWhich
);
2034 rAttr
.MergeValue(rItem
, TRUE
);
2037 nWhich
= aIter
.NextWhich();
2044 if( mpView
->IsTextEdit() )
2049 // --------------------------------------------------------------------
2051 const sal_uInt16 CELL_BEFORE
= 0x0001;
2052 const sal_uInt16 CELL_LEFT
= 0x0002;
2053 const sal_uInt16 CELL_RIGHT
= 0x0004;
2054 const sal_uInt16 CELL_AFTER
= 0x0008;
2056 const sal_uInt16 CELL_UPPER
= 0x0010;
2057 const sal_uInt16 CELL_TOP
= 0x0020;
2058 const sal_uInt16 CELL_BOTTOM
= 0x0040;
2059 const sal_uInt16 CELL_LOWER
= 0x0080;
2061 // --------------------------------------------------------------------
2063 static void ImplSetLinePreserveColor( SvxBoxItem
& rNewFrame
, const SvxBorderLine
* pNew
, USHORT nLine
)
2067 const SvxBorderLine
* pOld
= rNewFrame
.GetLine(nLine
);
2070 SvxBorderLine
aNewLine( *pNew
);
2071 aNewLine
.SetColor( pOld
->GetColor() );
2072 rNewFrame
.SetLine( &aNewLine
, nLine
);
2076 rNewFrame
.SetLine( pNew
, nLine
);
2079 // --------------------------------------------------------------------
2081 static void ImplApplyBoxItem( sal_uInt16 nCellFlags
, const SvxBoxItem
* pBoxItem
, const SvxBoxInfoItem
* pBoxInfoItem
, SvxBoxItem
& rNewFrame
)
2083 if( (nCellFlags
& (CELL_BEFORE
|CELL_AFTER
|CELL_UPPER
|CELL_LOWER
)) != 0 )
2085 // current cell is outside the selection
2087 if( (nCellFlags
& ( CELL_BEFORE
|CELL_AFTER
)) == 0 ) // check if its not nw or ne corner
2089 if( nCellFlags
& CELL_UPPER
)
2091 if( pBoxInfoItem
->IsValid(VALID_TOP
) )
2092 rNewFrame
.SetLine(0, BOX_LINE_BOTTOM
);
2094 else if( nCellFlags
& CELL_LOWER
)
2096 if( pBoxInfoItem
->IsValid(VALID_BOTTOM
) )
2097 rNewFrame
.SetLine( 0, BOX_LINE_TOP
);
2100 else if( (nCellFlags
& ( CELL_UPPER
|CELL_LOWER
)) == 0 ) // check if its not sw or se corner
2102 if( nCellFlags
& CELL_BEFORE
)
2104 if( pBoxInfoItem
->IsValid(VALID_LEFT
) )
2105 rNewFrame
.SetLine( 0, BOX_LINE_RIGHT
);
2107 else if( nCellFlags
& CELL_AFTER
)
2109 if( pBoxInfoItem
->IsValid(VALID_RIGHT
) )
2110 rNewFrame
.SetLine( 0, BOX_LINE_LEFT
);
2116 // current cell is inside the selection
2118 if( (nCellFlags
& CELL_LEFT
) ? pBoxInfoItem
->IsValid(VALID_LEFT
) : pBoxInfoItem
->IsValid(VALID_VERT
) )
2119 rNewFrame
.SetLine( (nCellFlags
& CELL_LEFT
) ? pBoxItem
->GetLeft() : pBoxInfoItem
->GetVert(), BOX_LINE_LEFT
);
2121 if( (nCellFlags
& CELL_RIGHT
) ? pBoxInfoItem
->IsValid(VALID_RIGHT
) : pBoxInfoItem
->IsValid(VALID_VERT
) )
2122 rNewFrame
.SetLine( (nCellFlags
& CELL_RIGHT
) ? pBoxItem
->GetRight() : pBoxInfoItem
->GetVert(), BOX_LINE_RIGHT
);
2124 if( (nCellFlags
& CELL_TOP
) ? pBoxInfoItem
->IsValid(VALID_TOP
) : pBoxInfoItem
->IsValid(VALID_HORI
) )
2125 rNewFrame
.SetLine( (nCellFlags
& CELL_TOP
) ? pBoxItem
->GetTop() : pBoxInfoItem
->GetHori(), BOX_LINE_TOP
);
2127 if( (nCellFlags
& CELL_BOTTOM
) ? pBoxInfoItem
->IsValid(VALID_BOTTOM
) : pBoxInfoItem
->IsValid(VALID_HORI
) )
2128 rNewFrame
.SetLine( (nCellFlags
& CELL_BOTTOM
) ? pBoxItem
->GetBottom() : pBoxInfoItem
->GetHori(), BOX_LINE_BOTTOM
);
2130 // apply distance to borders
2131 if( pBoxInfoItem
->IsValid( VALID_DISTANCE
) )
2132 for( USHORT nLine
= 0; nLine
< 4; ++nLine
)
2133 rNewFrame
.SetDistance( pBoxItem
->GetDistance( nLine
), nLine
);
2137 // --------------------------------------------------------------------
2139 static void ImplSetLineColor( SvxBoxItem
& rNewFrame
, USHORT nLine
, const Color
& rColor
)
2141 const SvxBorderLine
* pSourceLine
= rNewFrame
.GetLine( nLine
);
2144 SvxBorderLine
aLine( *pSourceLine
);
2145 aLine
.SetColor( rColor
);
2146 rNewFrame
.SetLine( &aLine
, nLine
);
2150 // --------------------------------------------------------------------
2152 static void ImplApplyLineColorItem( sal_uInt16 nCellFlags
, const SvxColorItem
* pLineColorItem
, SvxBoxItem
& rNewFrame
)
2154 const Color
aColor( pLineColorItem
->GetValue() );
2156 if( (nCellFlags
& (CELL_LOWER
|CELL_BEFORE
|CELL_AFTER
)) == 0 )
2157 ImplSetLineColor( rNewFrame
, BOX_LINE_BOTTOM
, aColor
);
2159 if( (nCellFlags
& (CELL_UPPER
|CELL_BEFORE
|CELL_AFTER
)) == 0 )
2160 ImplSetLineColor( rNewFrame
, BOX_LINE_TOP
, aColor
);
2162 if( (nCellFlags
& (CELL_UPPER
|CELL_LOWER
|CELL_AFTER
)) == 0 )
2163 ImplSetLineColor( rNewFrame
, BOX_LINE_RIGHT
, aColor
);
2165 if( (nCellFlags
& (CELL_UPPER
|CELL_LOWER
|CELL_BEFORE
)) == 0 )
2166 ImplSetLineColor( rNewFrame
, BOX_LINE_LEFT
, aColor
);
2169 // --------------------------------------------------------------------
2171 static void ImplApplyBorderLineItem( sal_uInt16 nCellFlags
, const SvxBorderLine
* pBorderLineItem
, SvxBoxItem
& rNewFrame
)
2173 if( (nCellFlags
& ( CELL_BEFORE
|CELL_AFTER
|CELL_UPPER
|CELL_LOWER
)) != 0 )
2175 if( (nCellFlags
& ( CELL_BEFORE
|CELL_AFTER
)) == 0 ) // check if its not nw or ne corner
2177 if( nCellFlags
& CELL_UPPER
)
2179 if( rNewFrame
.GetBottom() )
2180 ImplSetLinePreserveColor( rNewFrame
, pBorderLineItem
, BOX_LINE_BOTTOM
);
2182 else if( nCellFlags
& CELL_LOWER
)
2184 if( rNewFrame
.GetTop() )
2185 ImplSetLinePreserveColor( rNewFrame
, pBorderLineItem
, BOX_LINE_TOP
);
2188 else if( (nCellFlags
& ( CELL_UPPER
|CELL_LOWER
)) == 0 ) // check if its not sw or se corner
2190 if( nCellFlags
& CELL_BEFORE
)
2192 if( rNewFrame
.GetRight() )
2193 ImplSetLinePreserveColor( rNewFrame
, pBorderLineItem
, BOX_LINE_RIGHT
);
2195 else if( nCellFlags
& CELL_AFTER
)
2197 if( rNewFrame
.GetLeft() )
2198 ImplSetLinePreserveColor( rNewFrame
, pBorderLineItem
, BOX_LINE_LEFT
);
2204 if( rNewFrame
.GetBottom() )
2205 ImplSetLinePreserveColor( rNewFrame
, pBorderLineItem
, BOX_LINE_BOTTOM
);
2206 if( rNewFrame
.GetTop() )
2207 ImplSetLinePreserveColor( rNewFrame
, pBorderLineItem
, BOX_LINE_TOP
);
2208 if( rNewFrame
.GetRight() )
2209 ImplSetLinePreserveColor( rNewFrame
, pBorderLineItem
, BOX_LINE_RIGHT
);
2210 if( rNewFrame
.GetLeft() )
2211 ImplSetLinePreserveColor( rNewFrame
, pBorderLineItem
, BOX_LINE_LEFT
);
2215 // --------------------------------------------------------------------
2217 void SvxTableController::ApplyBorderAttr( const SfxItemSet
& rAttr
)
2221 const sal_Int32 nRowCount
= mxTable
->getRowCount();
2222 const sal_Int32 nColCount
= mxTable
->getColumnCount();
2223 if( nRowCount
&& nColCount
)
2225 const SvxBoxItem
* pBoxItem
= 0;
2226 if(SFX_ITEM_SET
== rAttr
.GetItemState(SDRATTR_TABLE_BORDER
, FALSE
) )
2227 pBoxItem
= dynamic_cast< const SvxBoxItem
* >( &rAttr
.Get( SDRATTR_TABLE_BORDER
) );
2229 const SvxBoxInfoItem
* pBoxInfoItem
= 0;
2230 if(SFX_ITEM_SET
== rAttr
.GetItemState(SDRATTR_TABLE_BORDER_INNER
, FALSE
) )
2231 pBoxInfoItem
= dynamic_cast< const SvxBoxInfoItem
* >( &rAttr
.Get( SDRATTR_TABLE_BORDER_INNER
) );
2233 const SvxColorItem
* pLineColorItem
= 0;
2234 if(SFX_ITEM_SET
== rAttr
.GetItemState(SID_FRAME_LINECOLOR
, FALSE
) )
2235 pLineColorItem
= dynamic_cast< const SvxColorItem
* >( &rAttr
.Get( SID_FRAME_LINECOLOR
) );
2237 const SvxBorderLine
* pBorderLineItem
= 0;
2238 if(SFX_ITEM_SET
== rAttr
.GetItemState(SID_FRAME_LINESTYLE
, FALSE
) )
2239 pBorderLineItem
= ((const SvxLineItem
&)rAttr
.Get( SID_FRAME_LINESTYLE
)).GetLine();
2241 if( pBoxInfoItem
&& !pBoxItem
)
2243 const static SvxBoxItem
gaEmptyBoxItem( SDRATTR_TABLE_BORDER
);
2244 pBoxItem
= &gaEmptyBoxItem
;
2246 else if( pBoxItem
&& !pBoxInfoItem
)
2248 const static SvxBoxInfoItem
gaEmptyBoxInfoItem( SDRATTR_TABLE_BORDER_INNER
);
2249 pBoxInfoItem
= &gaEmptyBoxInfoItem
;
2252 CellPos aStart
, aEnd
;
2253 getSelectedCells( aStart
, aEnd
);
2255 const sal_Int32 nLastRow
= std::min( aEnd
.mnRow
+ 2, nRowCount
);
2256 const sal_Int32 nLastCol
= std::min( aEnd
.mnCol
+ 2, nColCount
);
2258 for( sal_Int32 nRow
= std::max( aStart
.mnRow
- 1, (sal_Int32
)0 ); nRow
< nLastRow
; nRow
++ )
2260 sal_uInt16 nRowFlags
= 0;
2261 nRowFlags
|= (nRow
== aStart
.mnRow
) ? CELL_TOP
: 0;
2262 nRowFlags
|= (nRow
== aEnd
.mnRow
) ? CELL_BOTTOM
: 0;
2263 nRowFlags
|= (nRow
< aStart
.mnRow
) ? CELL_UPPER
: 0;
2264 nRowFlags
|= (nRow
> aEnd
.mnRow
) ? CELL_LOWER
: 0;
2266 for( sal_Int32 nCol
= std::max( aStart
.mnCol
- 1, (sal_Int32
)0 ); nCol
< nLastCol
; nCol
++ )
2268 CellRef
xCell( dynamic_cast< Cell
* >( mxTable
->getCellByPosition( nCol
, nRow
).get() ) );
2272 const SfxItemSet
& rSet
= xCell
->GetItemSet();
2273 const SvxBoxItem
* pOldOuter
= (const SvxBoxItem
*) &rSet
.Get( SDRATTR_TABLE_BORDER
);
2275 SvxBoxItem
aNewFrame( *pOldOuter
);
2277 sal_uInt16 nCellFlags
= nRowFlags
;
2278 nCellFlags
|= (nCol
== aStart
.mnCol
) ? CELL_LEFT
: 0;
2279 nCellFlags
|= (nCol
== aEnd
.mnCol
) ? CELL_RIGHT
: 0;
2280 nCellFlags
|= (nCol
< aStart
.mnCol
) ? CELL_BEFORE
: 0;
2281 nCellFlags
|= (nCol
> aEnd
.mnCol
) ? CELL_AFTER
: 0;
2283 if( pBoxItem
&& pBoxInfoItem
)
2284 ImplApplyBoxItem( nCellFlags
, pBoxItem
, pBoxInfoItem
, aNewFrame
);
2286 if( pLineColorItem
)
2287 ImplApplyLineColorItem( nCellFlags
, pLineColorItem
, aNewFrame
);
2289 if( pBorderLineItem
)
2290 ImplApplyBorderLineItem( nCellFlags
, pBorderLineItem
, aNewFrame
);
2292 if (aNewFrame
!= *pOldOuter
)
2294 SfxItemSet
aAttr(*rSet
.GetPool(), rSet
.GetRanges());
2295 aAttr
.Put(aNewFrame
);
2296 xCell
->SetMergedItemSetAndBroadcast( aAttr
, false );
2304 // --------------------------------------------------------------------
2306 void SvxTableController::UpdateTableShape()
2308 SdrObject
* pTableObj
= mxTableObj
.get();
2311 pTableObj
->ActionChanged();
2312 pTableObj
->BroadcastObjectChange();
2314 updateSelectionOverlay();
2318 // --------------------------------------------------------------------
2320 void SvxTableController::SetAttrToSelectedCells(const SfxItemSet
& rAttr
, bool bReplaceAll
)
2324 const bool bUndo
= mpModel
&& mpModel
->IsUndoEnabled();
2327 mpModel
->BegUndo( ImpGetResStr(STR_TABLE_NUMFORMAT
) );
2329 CellPos aStart
, aEnd
;
2330 getSelectedCells( aStart
, aEnd
);
2332 SfxItemSet
aAttr(*rAttr
.GetPool(), rAttr
.GetRanges());
2333 aAttr
.Put(rAttr
, TRUE
);
2335 const bool bFrame
= (rAttr
.GetItemState( SDRATTR_TABLE_BORDER
) == SFX_ITEM_SET
) || (rAttr
.GetItemState( SDRATTR_TABLE_BORDER_INNER
) == SFX_ITEM_SET
);
2339 aAttr
.ClearItem( SDRATTR_TABLE_BORDER
);
2340 aAttr
.ClearItem( SDRATTR_TABLE_BORDER_INNER
);
2343 for( sal_Int32 nRow
= aStart
.mnRow
; nRow
<= aEnd
.mnRow
; nRow
++ )
2345 for( sal_Int32 nCol
= aStart
.mnCol
; nCol
<= aEnd
.mnCol
; nCol
++ )
2347 CellRef
xCell( dynamic_cast< Cell
* >( mxTable
->getCellByPosition( nCol
, nRow
).get() ) );
2352 xCell
->SetMergedItemSetAndBroadcast(aAttr
, bReplaceAll
);
2359 ApplyBorderAttr( rAttr
);
2370 // --------------------------------------------------------------------
2372 bool SvxTableController::GetAttributes(SfxItemSet
& rTargetSet
, bool bOnlyHardAttr
) const
2374 if( mxTableObj
.is() && hasSelectedCells() )
2376 MergeAttrFromSelectedCells( rTargetSet
, bOnlyHardAttr
);
2378 if( mpView
->IsTextEdit() )
2380 if( mxTableObj
->GetOutlinerParaObject() )
2381 rTargetSet
.Put( SvxScriptTypeItem( mxTableObj
->GetOutlinerParaObject()->GetTextObject().GetScriptType() ) );
2383 OutlinerView
* pTextEditOutlinerView
= mpView
->GetTextEditOutlinerView();
2384 if(pTextEditOutlinerView
)
2386 // FALSE= InvalidItems nicht al Default, sondern als "Loecher" betrachten
2387 rTargetSet
.Put(pTextEditOutlinerView
->GetAttribs(), FALSE
);
2388 rTargetSet
.Put( SvxScriptTypeItem( pTextEditOutlinerView
->GetSelectedScriptType() ), FALSE
);
2400 // --------------------------------------------------------------------
2402 bool SvxTableController::SetAttributes(const SfxItemSet
& rSet
, bool bReplaceAll
)
2404 if( mbCellSelectionMode
|| mpView
->IsTextEdit() )
2406 SetAttrToSelectedCells( rSet
, bReplaceAll
);
2412 // --------------------------------------------------------------------
2414 bool SvxTableController::GetMarkedObjModel( SdrPage
* pNewPage
)
2416 if( mxTableObj
.is() && mbCellSelectionMode
&& pNewPage
) try
2418 ::sdr::table::SdrTableObj
& rTableObj
= *static_cast< ::sdr::table::SdrTableObj
* >( mxTableObj
.get() );
2420 CellPos aStart
, aEnd
;
2421 getSelectedCells( aStart
, aEnd
);
2423 SdrTableObj
* pNewTableObj
= rTableObj
.CloneRange( aStart
, aEnd
);
2425 pNewTableObj
->SetPage( pNewPage
);
2426 pNewTableObj
->SetModel( pNewPage
->GetModel() );
2428 SdrInsertReason
aReason(SDRREASON_VIEWCALL
);
2429 pNewPage
->InsertObject(pNewTableObj
,CONTAINER_APPEND
,&aReason
);
2435 DBG_ERROR( "svx::SvxTableController::GetMarkedObjModel(), exception caught!" );
2440 // --------------------------------------------------------------------
2442 bool SvxTableController::PasteObjModel( const SdrModel
& rModel
)
2444 if( mxTableObj
.is() && mpView
&& (rModel
.GetPageCount() >= 1) )
2446 const SdrPage
* pPastePage
= rModel
.GetPage(0);
2447 if( pPastePage
&& pPastePage
->GetObjCount() == 1 )
2449 SdrTableObj
* pPasteTableObj
= dynamic_cast< SdrTableObj
* >( pPastePage
->GetObj(0) );
2450 if( pPasteTableObj
)
2452 return PasteObject( pPasteTableObj
);
2460 // --------------------------------------------------------------------
2462 bool SvxTableController::PasteObject( SdrTableObj
* pPasteTableObj
)
2464 if( !pPasteTableObj
)
2467 Reference
< XTable
> xPasteTable( pPasteTableObj
->getTable() );
2468 if( !xPasteTable
.is() )
2474 sal_Int32 nPasteColumns
= xPasteTable
->getColumnCount();
2475 sal_Int32 nPasteRows
= xPasteTable
->getRowCount();
2477 CellPos aStart
, aEnd
;
2478 getSelectedCells( aStart
, aEnd
);
2480 if( mpView
->IsTextEdit() )
2481 mpView
->SdrEndTextEdit(sal_True
);
2483 sal_Int32 nColumns
= mxTable
->getColumnCount();
2484 sal_Int32 nRows
= mxTable
->getRowCount();
2486 const sal_Int32 nMissing
= nPasteRows
- ( nRows
- aStart
.mnRow
);
2489 Reference
< XTableRows
> xRows( mxTable
->getRows() );
2490 xRows
->insertByIndex( nRows
, nMissing
);
2491 nRows
= mxTable
->getRowCount();
2494 nPasteRows
= std::min( nPasteRows
, nRows
- aStart
.mnRow
);
2495 nPasteColumns
= std::min( nPasteColumns
, nColumns
- aStart
.mnCol
);
2497 // copy cell contents
2498 for( sal_Int32 nRow
= 0; nRow
< nPasteRows
; ++nRow
)
2500 for( sal_Int32 nCol
= 0; nCol
< nPasteColumns
; ++nCol
)
2502 CellRef
xTargetCell( dynamic_cast< Cell
* >( mxTable
->getCellByPosition( aStart
.mnCol
+ nCol
, aStart
.mnRow
+ nRow
).get() ) );
2503 if( xTargetCell
.is() && !xTargetCell
->isMerged() )
2505 xTargetCell
->AddUndo();
2506 xTargetCell
->cloneFrom( dynamic_cast< Cell
* >( xPasteTable
->getCellByPosition( nCol
, nRow
).get() ) );
2507 nCol
+= xTargetCell
->getColumnSpan() - 1;
2517 // --------------------------------------------------------------------
2519 IMPL_LINK( SvxTableController
, UpdateHdl
, void *, EMPTYARG
)
2523 if( mbCellSelectionMode
)
2525 CellPos
aStart( maCursorFirstPos
);
2526 CellPos
aEnd( maCursorLastPos
);
2529 if( aStart
!= maCursorFirstPos
|| aEnd
!= maCursorLastPos
)
2531 setSelectedCells( aStart
, aEnd
);
2534 updateSelectionOverlay();