1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include "tablecontroller.hxx"
32 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
33 #include <com/sun/star/container/XIndexAccess.hpp>
35 #include <com/sun/star/beans/XPropertySet.hpp>
36 #include <com/sun/star/table/XMergeableCellRange.hpp>
37 #include <com/sun/star/table/XMergeableCell.hpp>
39 #include <sal/config.h>
41 #include <vcl/svapp.hxx>
42 #include <svl/whiter.hxx>
44 #include <sfx2/request.hxx>
46 #include <editeng/scripttypeitem.hxx>
47 #include <svx/svdotable.hxx>
48 #include <svx/sdr/overlay/overlayobjectcell.hxx>
49 #include <svx/sdr/overlay/overlaymanager.hxx>
50 #include <svx/svxids.hrc>
51 #include <editeng/outlobj.hxx>
52 #include <svx/svdoutl.hxx>
53 #include <svx/svdpagv.hxx>
54 #include <svx/svdetc.hxx>
55 #include <editeng/editobj.hxx>
56 #include "editeng/editstat.hxx"
57 #include "editeng/unolingu.hxx"
58 #include "svx/sdrpagewindow.hxx"
59 #include <svx/selectioncontroller.hxx>
60 #include <svx/svdmodel.hxx>
61 #include "svx/sdrpaintwindow.hxx"
62 #include <svx/svxdlg.hxx>
63 #include <editeng/boxitem.hxx>
65 #include <editeng/borderline.hxx>
66 #include <editeng/colritem.hxx>
67 #include "editeng/bolnitem.hxx"
68 #include "svx/svdstr.hrc"
69 #include "svx/svdglob.hxx"
70 #include "svx/svdpage.hxx"
71 #include "tableundo.hxx"
72 #include "tablelayouter.hxx"
74 using ::editeng::SvxBorderLine
;
75 using ::rtl::OUString
;
76 using namespace ::sdr::table
;
77 using namespace ::com::sun::star
;
78 using namespace ::com::sun::star::uno
;
79 using namespace ::com::sun::star::table
;
80 using namespace ::com::sun::star::beans
;
81 using namespace ::com::sun::star::container
;
82 using namespace ::com::sun::star::text
;
83 using namespace ::com::sun::star::style
;
85 namespace sdr
{ namespace table
{
87 // --------------------------------------------------------------------
88 // class SvxTableControllerModifyListener
89 // --------------------------------------------------------------------
91 class SvxTableControllerModifyListener
: public ::cppu::WeakImplHelper1
< ::com::sun::star::util::XModifyListener
>
94 SvxTableControllerModifyListener( SvxTableController
* pController
)
95 : mpController( pController
) {}
98 virtual void SAL_CALL
modified( const ::com::sun::star::lang::EventObject
& aEvent
) throw (::com::sun::star::uno::RuntimeException
);
101 virtual void SAL_CALL
disposing( const ::com::sun::star::lang::EventObject
& Source
) throw (::com::sun::star::uno::RuntimeException
);
103 SvxTableController
* mpController
;
106 // --------------------------------------------------------------------
108 // --------------------------------------------------------------------
110 void SAL_CALL
SvxTableControllerModifyListener::modified( const ::com::sun::star::lang::EventObject
& ) throw (::com::sun::star::uno::RuntimeException
)
113 mpController
->onTableModified();
116 // --------------------------------------------------------------------
118 // --------------------------------------------------------------------
120 void SAL_CALL
SvxTableControllerModifyListener::disposing( const ::com::sun::star::lang::EventObject
& ) throw (::com::sun::star::uno::RuntimeException
)
125 // --------------------------------------------------------------------
126 // class SvxTableController
127 // --------------------------------------------------------------------
129 rtl::Reference
< sdr::SelectionController
> CreateTableController( SdrObjEditView
* pView
, const SdrObject
* pObj
, const rtl::Reference
< sdr::SelectionController
>& xRefController
)
131 return SvxTableController::create( pView
, pObj
, xRefController
);
134 // --------------------------------------------------------------------
136 rtl::Reference
< sdr::SelectionController
> SvxTableController::create( SdrObjEditView
* pView
, const SdrObject
* pObj
, const rtl::Reference
< sdr::SelectionController
>& xRefController
)
138 if( xRefController
.is() )
140 SvxTableController
* pController
= dynamic_cast< SvxTableController
* >( xRefController
.get() );
141 if( pController
&& (pController
->mxTableObj
.get() == pObj
) && (pController
->mpView
== pView
) )
142 return xRefController
;
144 return new SvxTableController( pView
, pObj
);
147 // --------------------------------------------------------------------
149 SvxTableController::SvxTableController( SdrObjEditView
* pView
, const SdrObject
* pObj
)
150 : mbCellSelectionMode(false)
151 , mbLeftButtonDown(false)
152 , mpSelectionOverlay(0)
153 , mpView( dynamic_cast< SdrView
* >( pView
) )
154 , mxTableObj( dynamic_cast< SdrTableObj
* >( const_cast< SdrObject
* >( pObj
) ) )
159 mpModel
= pObj
->GetModel();
161 if( mxTableObj
.is() )
163 static_cast< const SdrTableObj
* >( pObj
)->getActiveCellPos( maCursorFirstPos
);
164 maCursorLastPos
= maCursorFirstPos
;
166 Reference
< XTable
> xTable( static_cast< const SdrTableObj
* >( pObj
)->getTable() );
169 mxModifyListener
= new SvxTableControllerModifyListener( this );
170 xTable
->addModifyListener( mxModifyListener
);
172 mxTable
.set( dynamic_cast< TableModel
* >( xTable
.get() ) );
177 // --------------------------------------------------------------------
179 SvxTableController::~SvxTableController()
183 Application::RemoveUserEvent( mnUpdateEvent
);
186 if( mxModifyListener
.is() && mxTableObj
.get() )
188 Reference
< XTable
> xTable( static_cast< SdrTableObj
* >( mxTableObj
.get() )->getTable() );
191 xTable
->removeModifyListener( mxModifyListener
);
192 mxModifyListener
.clear();
197 // --------------------------------------------------------------------
199 const sal_uInt16 ACTION_NONE
= 0;
200 const sal_uInt16 ACTION_GOTO_FIRST_CELL
= 1;
201 const sal_uInt16 ACTION_GOTO_FIRST_COLUMN
= 2;
202 const sal_uInt16 ACTION_GOTO_FIRST_ROW
= 3;
203 const sal_uInt16 ACTION_GOTO_LEFT_CELL
= 4;
204 const sal_uInt16 ACTION_GOTO_UP_CELL
= 5;
205 const sal_uInt16 ACTION_GOTO_RIGHT_CELL
= 6;
206 const sal_uInt16 ACTION_GOTO_DOWN_CELL
= 7;
207 const sal_uInt16 ACTION_GOTO_LAST_CELL
= 8;
208 const sal_uInt16 ACTION_GOTO_LAST_COLUMN
= 9;
209 const sal_uInt16 ACTION_GOTO_LAST_ROW
= 10;
210 const sal_uInt16 ACTION_EDIT_CELL
= 11;
211 const sal_uInt16 ACTION_STOP_TEXT_EDIT
= 12;
212 const sal_uInt16 ACTION_REMOVE_SELECTION
= 13;
213 const sal_uInt16 ACTION_START_SELECTION
= 14;
214 const sal_uInt16 ACTION_HANDLED_BY_VIEW
= 15;
215 const sal_uInt16 ACTION_TAB
= 18;
217 bool SvxTableController::onKeyInput(const KeyEvent
& rKEvt
, Window
* pWindow
)
219 if( !checkTableObject() )
222 // check if we are read only
223 if( mpModel
&& mpModel
->IsReadOnly())
225 switch( rKEvt
.GetKeyCode().GetCode() )
230 case awt::Key::RIGHT
:
238 case awt::Key::ESCAPE
:
242 // tell the view we eat the event, no further processing needed
247 sal_uInt16 nAction
= getKeyboardAction( rKEvt
, pWindow
);
249 return executeAction( nAction
, ( rKEvt
.GetKeyCode().IsShift() ) ? sal_True
: sal_False
, pWindow
);
252 // --------------------------------------------------------------------
253 // ::com::sun::star::awt::XMouseClickHandler:
254 // --------------------------------------------------------------------
256 bool SvxTableController::onMouseButtonDown(const MouseEvent
& rMEvt
, Window
* pWindow
)
258 if( !pWindow
|| !checkTableObject() )
262 if( !rMEvt
.IsRight() && mpView
->PickAnything(rMEvt
,SDRMOUSEBUTTONDOWN
, aVEvt
) == SDRHIT_HANDLE
)
265 TableHitKind eHit
= static_cast< SdrTableObj
* >(mxTableObj
.get())->CheckTableHit( pWindow
->PixelToLogic(rMEvt
.GetPosPixel()), maMouseDownPos
.mnCol
, maMouseDownPos
.mnRow
, 0 );
267 mbLeftButtonDown
= (rMEvt
.GetClicks() == 1) && rMEvt
.IsLeft();
269 if( eHit
== SDRTABLEHIT_CELL
)
271 StartSelection( maMouseDownPos
);
275 if( rMEvt
.IsRight() && eHit
!= SDRTABLEHIT_NONE
)
276 return true; // right click will become context menu
278 // for cell selektion with the mouse remember our first hit
279 if( mbLeftButtonDown
)
283 Point
aPnt(rMEvt
.GetPosPixel());
285 aPnt
=pWindow
->PixelToLogic(aPnt
);
287 SdrHdl
* pHdl
= mpView
->PickHandle(aPnt
);
291 mbLeftButtonDown
= false;
295 ::sdr::table::SdrTableObj
* pTableObj
= dynamic_cast< ::sdr::table::SdrTableObj
* >( mxTableObj
.get() );
297 if( !pWindow
|| !pTableObj
|| eHit
== SDRTABLEHIT_NONE
)
299 mbLeftButtonDown
= false;
307 // --------------------------------------------------------------------
309 bool SvxTableController::onMouseButtonUp(const MouseEvent
& rMEvt
, Window
* /*pWin*/)
311 if( !checkTableObject() )
314 mbLeftButtonDown
= false;
316 if( rMEvt
.GetClicks() == 2 )
322 // --------------------------------------------------------------------
324 bool SvxTableController::onMouseMove(const MouseEvent
& rMEvt
, Window
* pWindow
)
326 if( !checkTableObject() )
335 SdrTableObj
* pTableObj
= dynamic_cast< SdrTableObj
* >( mxTableObj
.get() );
337 if( mbLeftButtonDown
&& pTableObj
&& pTableObj
->CheckTableHit( pWindow
->PixelToLogic(rMEvt
.GetPosPixel()), aPos
.mnCol
, aPos
.mnRow
, 0 ) != SDRTABLEHIT_NONE
)
339 if(aPos
!= maMouseDownPos
)
341 if( mbCellSelectionMode
)
343 setSelectedCells( maMouseDownPos
, aPos
);
348 StartSelection( maMouseDownPos
);
351 else if( mbCellSelectionMode
)
353 UpdateSelection( aPos
);
360 // --------------------------------------------------------------------
362 void SvxTableController::onSelectionHasChanged()
364 bool bSelected
= false;
366 SdrTableObj
* pTableObj
= dynamic_cast< SdrTableObj
* >( mxTableObj
.get() );
367 if( pTableObj
&& pTableObj
->IsTextEditActive() )
369 pTableObj
->getActiveCellPos( maCursorFirstPos
);
370 maCursorLastPos
= maCursorFirstPos
;
371 mbCellSelectionMode
= false;
375 const SdrMarkList
& rMarkList
= mpView
->GetMarkedObjectList();
376 if( rMarkList
.GetMarkCount() == 1 )
377 bSelected
= mxTableObj
.get() == rMarkList
.GetMark(0)->GetMarkedSdrObj();
382 updateSelectionOverlay();
386 destroySelectionOverlay();
390 // --------------------------------------------------------------------
392 void SvxTableController::GetState( SfxItemSet
& rSet
)
394 if( !mxTable
.is() || !mxTableObj
.is() || !mxTableObj
->GetModel() )
397 SfxItemSet
* pSet
= 0;
399 bool bVertDone
= false;
401 // Iterate over all requested items in the set.
402 SfxWhichIter
aIter( rSet
);
403 sal_uInt16 nWhich
= aIter
.FirstWhich();
408 case SID_TABLE_VERT_BOTTOM
:
409 case SID_TABLE_VERT_CENTER
:
410 case SID_TABLE_VERT_NONE
:
412 if( !mxTable
.is() || !mxTableObj
->GetModel() )
414 rSet
.DisableItem(nWhich
);
420 pSet
= new SfxItemSet( mxTableObj
->GetModel()->GetItemPool() );
421 MergeAttrFromSelectedCells(*pSet
, sal_False
);
424 SdrTextVertAdjust eAdj
= SDRTEXTVERTADJUST_BLOCK
;
426 if( pSet
->GetItemState( SDRATTR_TEXT_VERTADJUST
) != SFX_ITEM_DONTCARE
)
427 eAdj
= ((SdrTextVertAdjustItem
&)(pSet
->Get(SDRATTR_TEXT_VERTADJUST
))).GetValue();
429 rSet
.Put(SfxBoolItem(SID_TABLE_VERT_BOTTOM
, eAdj
== SDRTEXTVERTADJUST_BOTTOM
));
430 rSet
.Put(SfxBoolItem(SID_TABLE_VERT_CENTER
, eAdj
== SDRTEXTVERTADJUST_CENTER
));
431 rSet
.Put(SfxBoolItem(SID_TABLE_VERT_NONE
, eAdj
== SDRTEXTVERTADJUST_TOP
));
436 case SID_TABLE_DELETE_ROW
:
437 if( !mxTable
.is() || !hasSelectedCells() || (mxTable
->getRowCount() <= 1) )
438 rSet
.DisableItem(SID_TABLE_DELETE_ROW
);
440 case SID_TABLE_DELETE_COL
:
441 if( !mxTable
.is() || !hasSelectedCells() || (mxTable
->getColumnCount() <= 1) )
442 rSet
.DisableItem(SID_TABLE_DELETE_COL
);
444 case SID_TABLE_MERGE_CELLS
:
445 if( !mxTable
.is() || !hasSelectedCells() )
446 rSet
.DisableItem(SID_TABLE_MERGE_CELLS
);
448 case SID_TABLE_SPLIT_CELLS
:
449 if( !hasSelectedCells() || !mxTable
.is() )
450 rSet
.DisableItem(SID_TABLE_SPLIT_CELLS
);
453 case SID_OPTIMIZE_TABLE
:
454 case SID_TABLE_DISTRIBUTE_COLUMNS
:
455 case SID_TABLE_DISTRIBUTE_ROWS
:
457 bool bDistributeColumns
= false;
458 bool bDistributeRows
= false;
461 CellPos aStart
, aEnd
;
462 getSelectedCells( aStart
, aEnd
);
464 bDistributeColumns
= aStart
.mnCol
!= aEnd
.mnCol
;
465 bDistributeRows
= aStart
.mnRow
!= aEnd
.mnRow
;
467 if( !bDistributeColumns
&& !bDistributeRows
)
468 rSet
.DisableItem(SID_OPTIMIZE_TABLE
);
469 if( !bDistributeColumns
)
470 rSet
.DisableItem(SID_TABLE_DISTRIBUTE_COLUMNS
);
471 if( !bDistributeRows
)
472 rSet
.DisableItem(SID_TABLE_DISTRIBUTE_ROWS
);
477 case SID_TABLE_SORT_DIALOG
:
478 case SID_TABLE_AUTOSUM
:
479 // if( !mxTable.is() )
480 // rSet.DisableItem( nWhich );
485 nWhich
= aIter
.NextWhich();
491 // --------------------------------------------------------------------
493 void SvxTableController::onInsert( sal_uInt16 nSId
, const SfxItemSet
* pArgs
)
495 ::sdr::table::SdrTableObj
* pTableObj
= dynamic_cast< ::sdr::table::SdrTableObj
* >( mxTableObj
.get() );
499 if( mxTable
.is() ) try
502 bool bInsertAfter
= true;
503 sal_uInt16 nCount
= 0;
506 const SfxPoolItem
* pItem
= 0;
507 pArgs
->GetItemState(nSId
, sal_False
, &pItem
);
510 nCount
= ((const SfxInt16Item
* )pItem
)->GetValue();
511 if(SFX_ITEM_SET
== pArgs
->GetItemState(SID_TABLE_PARAM_INSERT_AFTER
, sal_True
, &pItem
))
512 bInsertAfter
= ((const SfxBoolItem
* )pItem
)->GetValue();
516 CellPos aStart
, aEnd
;
517 if( hasSelectedCells() )
519 getSelectedCells( aStart
, aEnd
);
525 aStart
.mnCol
= mxTable
->getColumnCount() - 1;
526 aStart
.mnRow
= mxTable
->getRowCount() - 1;
531 if( pTableObj
->IsTextEditActive() )
532 mpView
->SdrEndTextEdit(sal_True
);
536 const OUString
sSize( RTL_CONSTASCII_USTRINGPARAM( "Size" ) );
538 const bool bUndo
= mpModel
&& mpModel
->IsUndoEnabled();
542 case SID_TABLE_INSERT_COL
:
544 TableModelNotifyGuard
aGuard( mxTable
.get() );
548 mpModel
->BegUndo( ImpGetResStr(STR_TABLE_INSCOL
) );
549 mpModel
->AddUndo( mpModel
->GetSdrUndoFactory().CreateUndoGeoObject(*pTableObj
) );
552 Reference
< XTableColumns
> xCols( mxTable
->getColumns() );
553 const sal_Int32 nNewColumns
= (nCount
== 0) ? (aEnd
.mnCol
- aStart
.mnCol
+ 1) : nCount
;
554 const sal_Int32 nNewStartColumn
= aEnd
.mnCol
+ (bInsertAfter
? 1 : 0);
555 xCols
->insertByIndex( nNewStartColumn
, nNewColumns
);
557 for( sal_Int32 nOffset
= 0; nOffset
< nNewColumns
; nOffset
++ )
559 Reference
< XPropertySet
>( xCols
->getByIndex( aEnd
.mnCol
+ nOffset
+ 1 ), UNO_QUERY_THROW
)->
560 setPropertyValue( sSize
,
561 Reference
< XPropertySet
>( xCols
->getByIndex( aStart
.mnCol
+ nOffset
), UNO_QUERY_THROW
)->
562 getPropertyValue( sSize
) );
568 aStart
.mnCol
= nNewStartColumn
;
570 aEnd
.mnCol
= aStart
.mnCol
+ nNewColumns
- 1;
571 aEnd
.mnRow
= mxTable
->getRowCount() - 1;
575 case SID_TABLE_INSERT_ROW
:
577 TableModelNotifyGuard
aGuard( mxTable
.get() );
581 mpModel
->BegUndo( ImpGetResStr(STR_TABLE_INSROW
) );
582 mpModel
->AddUndo( mpModel
->GetSdrUndoFactory().CreateUndoGeoObject(*pTableObj
) );
585 Reference
< XTableRows
> xRows( mxTable
->getRows() );
586 const sal_Int32 nNewRows
= (nCount
== 0) ? (aEnd
.mnRow
- aStart
.mnRow
+ 1) : nCount
;
587 const sal_Int32 nNewRowStart
= aEnd
.mnRow
+ (bInsertAfter
? 1 : 0);
588 xRows
->insertByIndex( nNewRowStart
, nNewRows
);
590 for( sal_Int32 nOffset
= 0; nOffset
< nNewRows
; nOffset
++ )
592 Reference
< XPropertySet
>( xRows
->getByIndex( aEnd
.mnRow
+ nOffset
+ 1 ), UNO_QUERY_THROW
)->
593 setPropertyValue( sSize
,
594 Reference
< XPropertySet
>( xRows
->getByIndex( aStart
.mnRow
+ nOffset
), UNO_QUERY_THROW
)->
595 getPropertyValue( sSize
) );
602 aStart
.mnRow
= nNewRowStart
;
603 aEnd
.mnCol
= mxTable
->getColumnCount() - 1;
604 aEnd
.mnRow
= aStart
.mnRow
+ nNewRows
- 1;
609 StartSelection( aStart
);
610 UpdateSelection( aEnd
);
614 OSL_FAIL("svx::SvxTableController::onInsert(), exception caught!");
618 // --------------------------------------------------------------------
620 void SvxTableController::onDelete( sal_uInt16 nSId
)
622 ::sdr::table::SdrTableObj
* pTableObj
= dynamic_cast< ::sdr::table::SdrTableObj
* >( mxTableObj
.get() );
626 if( mxTable
.is() && hasSelectedCells() )
628 CellPos aStart
, aEnd
;
629 getSelectedCells( aStart
, aEnd
);
631 if( pTableObj
->IsTextEditActive() )
632 mpView
->SdrEndTextEdit(sal_True
);
636 bool bDeleteTable
= false;
639 case SID_TABLE_DELETE_COL
:
641 const sal_Int32 nRemovedColumns
= aEnd
.mnCol
- aStart
.mnCol
+ 1;
642 if( nRemovedColumns
== mxTable
->getColumnCount() )
648 Reference
< XTableColumns
> xCols( mxTable
->getColumns() );
649 xCols
->removeByIndex( aStart
.mnCol
, nRemovedColumns
);
654 case SID_TABLE_DELETE_ROW
:
656 const sal_Int32 nRemovedRows
= aEnd
.mnRow
- aStart
.mnRow
+ 1;
657 if( nRemovedRows
== mxTable
->getRowCount() )
663 Reference
< XTableRows
> xRows( mxTable
->getRows() );
664 xRows
->removeByIndex( aStart
.mnRow
, nRemovedRows
);
671 mpView
->DeleteMarkedObj();
677 // --------------------------------------------------------------------
679 void SvxTableController::onSelect( sal_uInt16 nSId
)
683 const sal_Int32 nRowCount
= mxTable
->getRowCount();
684 const sal_Int32 nColCount
= mxTable
->getColumnCount();
685 if( nRowCount
&& nColCount
)
687 CellPos aStart
, aEnd
;
688 getSelectedCells( aStart
, aEnd
);
692 case SID_TABLE_SELECT_ALL
:
693 aEnd
.mnCol
= 0; aEnd
.mnRow
= 0;
694 aStart
.mnCol
= nColCount
- 1; aStart
.mnRow
= nRowCount
- 1;
696 case SID_TABLE_SELECT_COL
:
697 aEnd
.mnRow
= nRowCount
- 1;
700 case SID_TABLE_SELECT_ROW
:
701 aEnd
.mnCol
= nColCount
- 1;
706 StartSelection( aEnd
);
707 gotoCell( aStart
, true, 0 );
712 // --------------------------------------------------------------------
713 void SvxTableController::onFormatTable( SfxRequest
& rReq
)
715 ::sdr::table::SdrTableObj
* pTableObj
= dynamic_cast< ::sdr::table::SdrTableObj
* >( mxTableObj
.get() );
719 const SfxItemSet
* pArgs
= rReq
.GetArgs();
721 if( !pArgs
&& pTableObj
->GetModel() )
723 SfxItemSet
aNewAttr( pTableObj
->GetModel()->GetItemPool() );
724 MergeAttrFromSelectedCells(aNewAttr
, sal_False
);
726 // merge drawing layer text distance items into SvxBoxItem used by the dialog
727 SvxBoxItem
aBoxItem( static_cast< const SvxBoxItem
& >( aNewAttr
.Get( SDRATTR_TABLE_BORDER
) ) );
728 aBoxItem
.SetDistance( sal::static_int_cast
< sal_uInt16
>( ((SdrTextLeftDistItem
&)(aNewAttr
.Get(SDRATTR_TEXT_LEFTDIST
))).GetValue()), BOX_LINE_LEFT
);
729 aBoxItem
.SetDistance( sal::static_int_cast
< sal_uInt16
>( ((SdrTextRightDistItem
&)(aNewAttr
.Get(SDRATTR_TEXT_RIGHTDIST
))).GetValue()), BOX_LINE_RIGHT
);
730 aBoxItem
.SetDistance( sal::static_int_cast
< sal_uInt16
>( ((SdrTextUpperDistItem
&)(aNewAttr
.Get(SDRATTR_TEXT_UPPERDIST
))).GetValue()), BOX_LINE_TOP
);
731 aBoxItem
.SetDistance( sal::static_int_cast
< sal_uInt16
>( ((SdrTextLowerDistItem
&)(aNewAttr
.Get(SDRATTR_TEXT_LOWERDIST
))).GetValue()), BOX_LINE_BOTTOM
);
732 aNewAttr
.Put( aBoxItem
);
734 SvxAbstractDialogFactory
* pFact
= SvxAbstractDialogFactory::Create();
735 std::auto_ptr
< SfxAbstractTabDialog
> pDlg( pFact
? pFact
->CreateSvxFormatCellsDialog( NULL
, &aNewAttr
, pTableObj
->GetModel(), pTableObj
) : 0 );
736 if( pDlg
.get() && pDlg
->Execute() )
738 SfxItemSet
aNewSet( *(pDlg
->GetOutputItemSet ()) );
740 SvxBoxItem
aNewBoxItem( static_cast< const SvxBoxItem
& >( aNewSet
.Get( SDRATTR_TABLE_BORDER
) ) );
742 if( aNewBoxItem
.GetDistance( BOX_LINE_LEFT
) != aBoxItem
.GetDistance( BOX_LINE_LEFT
) )
743 aNewSet
.Put(SdrTextLeftDistItem( aNewBoxItem
.GetDistance( BOX_LINE_LEFT
) ) );
745 if( aNewBoxItem
.GetDistance( BOX_LINE_RIGHT
) != aBoxItem
.GetDistance( BOX_LINE_RIGHT
) )
746 aNewSet
.Put(SdrTextRightDistItem( aNewBoxItem
.GetDistance( BOX_LINE_RIGHT
) ) );
748 if( aNewBoxItem
.GetDistance( BOX_LINE_TOP
) != aBoxItem
.GetDistance( BOX_LINE_TOP
) )
749 aNewSet
.Put(SdrTextUpperDistItem( aNewBoxItem
.GetDistance( BOX_LINE_TOP
) ) );
751 if( aNewBoxItem
.GetDistance( BOX_LINE_BOTTOM
) != aBoxItem
.GetDistance( BOX_LINE_BOTTOM
) )
752 aNewSet
.Put(SdrTextLowerDistItem( aNewBoxItem
.GetDistance( BOX_LINE_BOTTOM
) ) );
754 SetAttrToSelectedCells(aNewSet
, sal_False
);
760 // --------------------------------------------------------------------
762 void SvxTableController::Execute( SfxRequest
& rReq
)
764 const sal_uInt16 nSId
= rReq
.GetSlot();
767 case SID_TABLE_INSERT_ROW
:
768 case SID_TABLE_INSERT_COL
:
769 onInsert( nSId
, rReq
.GetArgs() );
771 case SID_TABLE_DELETE_ROW
:
772 case SID_TABLE_DELETE_COL
:
775 case SID_TABLE_SELECT_ALL
:
776 case SID_TABLE_SELECT_COL
:
777 case SID_TABLE_SELECT_ROW
:
780 case SID_FORMAT_TABLE_DLG
:
781 onFormatTable( rReq
);
784 case SID_FRAME_LINESTYLE
:
785 case SID_FRAME_LINECOLOR
:
786 case SID_ATTR_BORDER
:
788 const SfxItemSet
* pArgs
= rReq
.GetArgs();
790 ApplyBorderAttr( *pArgs
);
794 case SID_ATTR_FILL_STYLE
:
796 const SfxItemSet
* pArgs
= rReq
.GetArgs();
798 SetAttributes( *pArgs
, false );
802 case SID_TABLE_MERGE_CELLS
:
806 case SID_TABLE_SPLIT_CELLS
:
810 case SID_TABLE_DISTRIBUTE_COLUMNS
:
814 case SID_TABLE_DISTRIBUTE_ROWS
:
818 case SID_TABLE_VERT_BOTTOM
:
819 case SID_TABLE_VERT_CENTER
:
820 case SID_TABLE_VERT_NONE
:
825 case SID_TABLE_SORT_DIALOG
:
826 case SID_TABLE_AUTOSUM
:
830 case SID_TABLE_STYLE
:
831 SetTableStyle( rReq
.GetArgs() );
834 case SID_TABLE_STYLE_SETTINGS
:
835 SetTableStyleSettings( rReq
.GetArgs() );
840 void SvxTableController::SetTableStyle( const SfxItemSet
* pArgs
)
842 SdrTableObj
* pTableObj
= dynamic_cast< ::sdr::table::SdrTableObj
* >( mxTableObj
.get() );
843 SdrModel
* pModel
= pTableObj
? pTableObj
->GetModel() : 0;
845 if( !pTableObj
|| !pModel
|| !pArgs
|| (SFX_ITEM_SET
!= pArgs
->GetItemState(SID_TABLE_STYLE
, sal_False
)) )
848 const SfxStringItem
* pArg
= dynamic_cast< const SfxStringItem
* >( &pArgs
->Get( SID_TABLE_STYLE
) );
849 if( pArg
&& mxTable
.is() ) try
851 Reference
< XStyleFamiliesSupplier
> xSFS( pModel
->getUnoModel(), UNO_QUERY_THROW
);
852 Reference
< XNameAccess
> xFamilyNameAccess( xSFS
->getStyleFamilies(), UNO_QUERY_THROW
);
853 const OUString
sFamilyName( RTL_CONSTASCII_USTRINGPARAM( "table" ) );
854 Reference
< XNameAccess
> xTableFamilyAccess( xFamilyNameAccess
->getByName( sFamilyName
), UNO_QUERY_THROW
);
856 if( xTableFamilyAccess
->hasByName( pArg
->GetValue() ) )
858 // found table style with the same name
859 Reference
< XIndexAccess
> xNewTableStyle( xTableFamilyAccess
->getByName( pArg
->GetValue() ), UNO_QUERY_THROW
);
861 const bool bUndo
= pModel
->IsUndoEnabled();
865 pModel
->BegUndo( ImpGetResStr(STR_TABLE_STYLE
) );
866 pModel
->AddUndo( new TableStyleUndo( *pTableObj
) );
869 pTableObj
->setTableStyle( xNewTableStyle
);
871 const sal_Int32 nRowCount
= mxTable
->getRowCount();
872 const sal_Int32 nColCount
= mxTable
->getColumnCount();
873 for( sal_Int32 nRow
= 0; nRow
< nRowCount
; nRow
++ )
875 for( sal_Int32 nCol
= 0; nCol
< nColCount
; nCol
++ ) try
877 CellRef
xCell( dynamic_cast< Cell
* >( mxTable
->getCellByPosition( nCol
, nRow
).get() ) );
880 SfxItemSet
aSet( xCell
->GetItemSet() );
881 bool bChanges
= false;
882 const SfxItemSet
& rStyleAttribs
= xCell
->GetStyleSheet()->GetItemSet();
884 for ( sal_uInt16 nWhich
= SDRATTR_START
; nWhich
<= SDRATTR_TABLE_LAST
; nWhich
++ )
886 if( (rStyleAttribs
.GetItemState( nWhich
) == SFX_ITEM_ON
) && (aSet
.GetItemState( nWhich
) == SFX_ITEM_ON
) )
888 aSet
.ClearItem( nWhich
);
898 xCell
->SetMergedItemSetAndBroadcast( aSet
, sal_True
);
904 OSL_FAIL( "svx::SvxTableController::SetTableStyle(), exception caught!" );
914 OSL_FAIL( "svx::SvxTableController::SetTableStyle(), exception caught!" );
918 void SvxTableController::SetTableStyleSettings( const SfxItemSet
* pArgs
)
920 SdrTableObj
* pTableObj
= dynamic_cast< ::sdr::table::SdrTableObj
* >( mxTableObj
.get() );
921 SdrModel
* pModel
= pTableObj
? pTableObj
->GetModel() : 0;
923 if( !pTableObj
|| !pModel
)
926 TableStyleSettings
aSettings( pTableObj
->getTableStyleSettings() );
928 const SfxPoolItem
*pPoolItem
=NULL
;
930 if( (SFX_ITEM_SET
== pArgs
->GetItemState(ID_VAL_USEFIRSTROWSTYLE
, sal_False
,&pPoolItem
)) )
931 aSettings
.mbUseFirstRow
= static_cast< const SfxBoolItem
* >(pPoolItem
)->GetValue();
933 if( (SFX_ITEM_SET
== pArgs
->GetItemState(ID_VAL_USELASTROWSTYLE
, sal_False
,&pPoolItem
)) )
934 aSettings
.mbUseLastRow
= static_cast< const SfxBoolItem
* >(pPoolItem
)->GetValue();
936 if( (SFX_ITEM_SET
== pArgs
->GetItemState(ID_VAL_USEBANDINGROWSTYLE
, sal_False
,&pPoolItem
)) )
937 aSettings
.mbUseRowBanding
= static_cast< const SfxBoolItem
* >(pPoolItem
)->GetValue();
939 if( (SFX_ITEM_SET
== pArgs
->GetItemState(ID_VAL_USEFIRSTCOLUMNSTYLE
, sal_False
,&pPoolItem
)) )
940 aSettings
.mbUseFirstColumn
= static_cast< const SfxBoolItem
* >(pPoolItem
)->GetValue();
942 if( (SFX_ITEM_SET
== pArgs
->GetItemState(ID_VAL_USELASTCOLUMNSTYLE
, sal_False
,&pPoolItem
)) )
943 aSettings
.mbUseLastColumn
= static_cast< const SfxBoolItem
* >(pPoolItem
)->GetValue();
945 if( (SFX_ITEM_SET
== pArgs
->GetItemState(ID_VAL_USEBANDINGCOLUMNSTYLE
, sal_False
,&pPoolItem
)) )
946 aSettings
.mbUseColumnBanding
= static_cast< const SfxBoolItem
* >(pPoolItem
)->GetValue();
948 if( aSettings
== pTableObj
->getTableStyleSettings() )
951 const bool bUndo
= pModel
->IsUndoEnabled();
955 pModel
->BegUndo( ImpGetResStr(STR_TABLE_STYLE_SETTINGS
) );
956 pModel
->AddUndo( new TableStyleUndo( *pTableObj
) );
959 pTableObj
->setTableStyleSettings( aSettings
);
965 void SvxTableController::SetVertical( sal_uInt16 nSId
)
967 SdrTableObj
* pTableObj
= dynamic_cast< ::sdr::table::SdrTableObj
* >( mxTableObj
.get() );
968 if( mxTable
.is() && pTableObj
)
970 TableModelNotifyGuard
aGuard( mxTable
.get() );
972 CellPos aStart
, aEnd
;
973 getSelectedCells( aStart
, aEnd
);
975 SdrTextVertAdjust eAdj
= SDRTEXTVERTADJUST_TOP
;
979 case SID_TABLE_VERT_BOTTOM
:
980 eAdj
= SDRTEXTVERTADJUST_BOTTOM
;
982 case SID_TABLE_VERT_CENTER
:
983 eAdj
= SDRTEXTVERTADJUST_CENTER
;
985 //case SID_TABLE_VERT_NONE:
990 SdrTextVertAdjustItem
aItem( eAdj
);
992 for( sal_Int32 nRow
= aStart
.mnRow
; nRow
<= aEnd
.mnRow
; nRow
++ )
994 for( sal_Int32 nCol
= aStart
.mnCol
; nCol
<= aEnd
.mnCol
; nCol
++ )
996 CellRef
xCell( dynamic_cast< Cell
* >( mxTable
->getCellByPosition( nCol
, nRow
).get() ) );
998 xCell
->SetMergedItem(aItem
);
1006 void SvxTableController::MergeMarkedCells()
1008 CellPos aStart
, aEnd
;
1009 getSelectedCells( aStart
, aEnd
);
1010 SdrTableObj
* pTableObj
= dynamic_cast< ::sdr::table::SdrTableObj
* >( mxTableObj
.get() );
1013 if( pTableObj
->IsTextEditActive() )
1014 mpView
->SdrEndTextEdit(sal_True
);
1016 TableModelNotifyGuard
aGuard( mxTable
.get() );
1017 MergeRange( aStart
.mnCol
, aStart
.mnRow
, aEnd
.mnCol
, aEnd
.mnRow
);
1021 void SvxTableController::SplitMarkedCells()
1025 CellPos aStart
, aEnd
;
1026 getSelectedCells( aStart
, aEnd
);
1028 SvxAbstractDialogFactory
* pFact
= SvxAbstractDialogFactory::Create();
1029 std::auto_ptr
< SvxAbstractSplittTableDialog
> xDlg( pFact
? pFact
->CreateSvxSplittTableDialog( NULL
, false, 99, 99 ) : 0 );
1030 if( xDlg
.get() && xDlg
->Execute() )
1032 const sal_Int32 nCount
= xDlg
->GetCount() - 1;
1036 getSelectedCells( aStart
, aEnd
);
1038 Reference
< XMergeableCellRange
> xRange( mxTable
->createCursorByRange( mxTable
->getCellRangeByPosition( aStart
.mnCol
, aStart
.mnRow
, aEnd
.mnCol
, aEnd
.mnRow
) ), UNO_QUERY_THROW
);
1040 const sal_Int32 nRowCount
= mxTable
->getRowCount();
1041 const sal_Int32 nColCount
= mxTable
->getColumnCount();
1044 SdrTableObj
* pTableObj
= dynamic_cast< SdrTableObj
* >( mxTableObj
.get() );
1047 if( pTableObj
->IsTextEditActive() )
1048 mpView
->SdrEndTextEdit(sal_True
);
1050 TableModelNotifyGuard
aGuard( mxTable
.get() );
1052 const bool bUndo
= mpModel
&& mpModel
->IsUndoEnabled();
1055 mpModel
->BegUndo( ImpGetResStr(STR_TABLE_SPLIT
) );
1056 mpModel
->AddUndo( mpModel
->GetSdrUndoFactory().CreateUndoGeoObject(*pTableObj
) );
1059 if( xDlg
->IsHorizontal() )
1061 xRange
->split( 0, nCount
);
1065 xRange
->split( nCount
, 0 );
1071 aEnd
.mnRow
+= mxTable
->getRowCount() - nRowCount
;
1072 aEnd
.mnCol
+= mxTable
->getColumnCount() - nColCount
;
1074 setSelectedCells( aStart
, aEnd
);
1079 void SvxTableController::DistributeColumns()
1081 SdrTableObj
* pTableObj
= dynamic_cast< SdrTableObj
* >( mxTableObj
.get() );
1084 const bool bUndo
= mpModel
&& mpModel
->IsUndoEnabled();
1087 mpModel
->BegUndo( ImpGetResStr(STR_TABLE_DISTRIBUTE_COLUMNS
) );
1088 mpModel
->AddUndo( mpModel
->GetSdrUndoFactory().CreateUndoGeoObject(*pTableObj
) );
1091 CellPos aStart
, aEnd
;
1092 getSelectedCells( aStart
, aEnd
);
1093 pTableObj
->DistributeColumns( aStart
.mnCol
, aEnd
.mnCol
);
1100 void SvxTableController::DistributeRows()
1102 SdrTableObj
* pTableObj
= dynamic_cast< SdrTableObj
* >( mxTableObj
.get() );
1105 const bool bUndo
= mpModel
&& mpModel
->IsUndoEnabled();
1108 mpModel
->BegUndo( ImpGetResStr(STR_TABLE_DISTRIBUTE_ROWS
) );
1109 mpModel
->AddUndo( mpModel
->GetSdrUndoFactory().CreateUndoGeoObject(*pTableObj
) );
1112 CellPos aStart
, aEnd
;
1113 getSelectedCells( aStart
, aEnd
);
1114 pTableObj
->DistributeRows( aStart
.mnRow
, aEnd
.mnRow
);
1121 bool SvxTableController::DeleteMarked()
1123 if( mbCellSelectionMode
)
1127 CellPos aStart
, aEnd
;
1128 getSelectedCells( aStart
, aEnd
);
1129 for( sal_Int32 nRow
= aStart
.mnRow
; nRow
<= aEnd
.mnRow
; nRow
++ )
1131 for( sal_Int32 nCol
= aStart
.mnCol
; nCol
<= aEnd
.mnCol
; nCol
++ )
1133 CellRef
xCell( dynamic_cast< Cell
* >( mxTable
->getCellByPosition( nCol
, nRow
).get() ) );
1135 xCell
->SetOutlinerParaObject( 0 );
1147 bool SvxTableController::GetStyleSheet( SfxStyleSheet
*& rpStyleSheet
) const
1149 if( hasSelectedCells() )
1155 SfxStyleSheet
* pRet
=0;
1158 CellPos aStart
, aEnd
;
1159 const_cast<SvxTableController
&>(*this).getSelectedCells( aStart
, aEnd
);
1161 for( sal_Int32 nRow
= aStart
.mnRow
; nRow
<= aEnd
.mnRow
; nRow
++ )
1163 for( sal_Int32 nCol
= aStart
.mnCol
; nCol
<= aEnd
.mnCol
; nCol
++ )
1165 CellRef
xCell( dynamic_cast< Cell
* >( mxTable
->getCellByPosition( nCol
, nRow
).get() ) );
1168 SfxStyleSheet
* pSS
=xCell
->GetStyleSheet();
1173 else if(pRet
!= pSS
)
1181 rpStyleSheet
= pRet
;
1188 bool SvxTableController::SetStyleSheet( SfxStyleSheet
* pStyleSheet
, bool bDontRemoveHardAttr
)
1190 if( hasSelectedCells() && (!pStyleSheet
|| pStyleSheet
->GetFamily() == SFX_STYLE_FAMILY_FRAME
) )
1194 CellPos aStart
, aEnd
;
1195 getSelectedCells( aStart
, aEnd
);
1197 for( sal_Int32 nRow
= aStart
.mnRow
; nRow
<= aEnd
.mnRow
; nRow
++ )
1199 for( sal_Int32 nCol
= aStart
.mnCol
; nCol
<= aEnd
.mnCol
; nCol
++ )
1201 CellRef
xCell( dynamic_cast< Cell
* >( mxTable
->getCellByPosition( nCol
, nRow
).get() ) );
1203 xCell
->SetStyleSheet(pStyleSheet
,bDontRemoveHardAttr
);
1214 // --------------------------------------------------------------------
1216 // --------------------------------------------------------------------
1218 bool SvxTableController::checkTableObject()
1220 return mxTableObj
.is();
1223 // --------------------------------------------------------------------
1225 sal_uInt16
SvxTableController::getKeyboardAction( const KeyEvent
& rKEvt
, Window
* /*pWindow*/ )
1227 const bool bMod1
= rKEvt
.GetKeyCode().IsMod1(); // ctrl
1228 const bool bMod2
= rKEvt
.GetKeyCode().IsMod2() != 0; // Alt
1230 const bool bTextEdit
= mpView
->IsTextEdit();
1232 sal_uInt16 nAction
= ACTION_HANDLED_BY_VIEW
;
1234 ::sdr::table::SdrTableObj
* pTableObj
= dynamic_cast< ::sdr::table::SdrTableObj
* >( mxTableObj
.get() );
1238 // handle special keys
1239 const sal_Int16 nCode
= rKEvt
.GetKeyCode().GetCode();
1242 case awt::Key::ESCAPE
: // handle escape
1246 // escape during text edit ends text edit
1247 nAction
= ACTION_STOP_TEXT_EDIT
;
1249 if( mbCellSelectionMode
)
1251 // escape with selected cells removes selection
1252 nAction
= ACTION_REMOVE_SELECTION
;
1256 case awt::Key::RETURN
: // handle return
1258 if( !bMod1
&& !bMod2
&& !bTextEdit
)
1260 // when not already editing, return starts text edit
1261 setSelectionStart( pTableObj
->getFirstCell() );
1262 nAction
= ACTION_EDIT_CELL
;
1266 case awt::Key::F2
: // f2 toggles text edit
1268 if( bMod1
|| bMod2
) // f2 with modifiers is handled by the view
1271 else if( bTextEdit
)
1273 // f2 during text edit stops text edit
1274 nAction
= ACTION_STOP_TEXT_EDIT
;
1276 else if( mbCellSelectionMode
)
1278 // f2 with selected cells removes selection
1279 nAction
= ACTION_REMOVE_SELECTION
;
1283 // f2 with no selection and no text edit starts text edit
1284 setSelectionStart( pTableObj
->getFirstCell() );
1285 nAction
= ACTION_EDIT_CELL
;
1289 case awt::Key::HOME
:
1290 case awt::Key::NUM7
:
1292 if( (bMod1
|| bMod2
) && (bTextEdit
|| mbCellSelectionMode
) )
1294 if( bMod1
&& !bMod2
)
1296 // strg + home jumps to first cell
1297 nAction
= ACTION_GOTO_FIRST_CELL
;
1299 else if( !bMod1
&& bMod2
)
1301 // alt + home jumps to first column
1302 nAction
= ACTION_GOTO_FIRST_COLUMN
;
1308 case awt::Key::NUM1
:
1310 if( (bMod1
|| bMod2
) && (bTextEdit
|| mbCellSelectionMode
) )
1312 if( bMod1
&& !bMod2
)
1314 // strg + end jumps to last cell
1315 nAction
= ACTION_GOTO_LAST_CELL
;
1317 else if( !bMod1
&& bMod2
)
1319 // alt + home jumps to last column
1320 nAction
= ACTION_GOTO_LAST_COLUMN
;
1328 if( bTextEdit
|| mbCellSelectionMode
)
1329 nAction
= ACTION_TAB
;
1334 case awt::Key::NUM8
:
1335 case awt::Key::DOWN
:
1336 case awt::Key::NUM2
:
1337 case awt::Key::LEFT
:
1338 case awt::Key::NUM4
:
1339 case awt::Key::RIGHT
:
1340 case awt::Key::NUM6
:
1342 bool bTextMove
= false;
1344 if( !bMod1
&& bMod2
)
1346 if( (nCode
== awt::Key::UP
) || (nCode
== awt::Key::NUM8
) )
1348 nAction
= ACTION_GOTO_LEFT_CELL
;
1350 else if( (nCode
== awt::Key::DOWN
) || (nCode
== awt::Key::NUM2
) )
1352 nAction
= ACTION_GOTO_RIGHT_CELL
;
1359 OutlinerView
* pOLV
= mpView
->GetTextEditOutlinerView();
1363 // during text edit, check if we navigate out of the cell
1364 ESelection aOldSelection
= pOLV
->GetSelection();
1365 pOLV
->PostKeyEvent(rKEvt
);
1366 bTextMove
= pOLV
&& ( aOldSelection
.IsEqual(pOLV
->GetSelection()) );
1369 nAction
= ACTION_NONE
;
1374 if( mbCellSelectionMode
|| bTextMove
)
1376 // no text edit, navigate in cells if selection active
1379 case awt::Key::LEFT
:
1380 case awt::Key::NUM4
:
1381 nAction
= ACTION_GOTO_LEFT_CELL
;
1383 case awt::Key::RIGHT
:
1384 case awt::Key::NUM6
:
1385 nAction
= ACTION_GOTO_RIGHT_CELL
;
1387 case awt::Key::DOWN
:
1388 case awt::Key::NUM2
:
1389 nAction
= ACTION_GOTO_DOWN_CELL
;
1392 case awt::Key::NUM8
:
1393 nAction
= ACTION_GOTO_UP_CELL
;
1399 case awt::Key::PAGEUP
:
1401 nAction
= ACTION_GOTO_FIRST_ROW
;
1404 case awt::Key::PAGEDOWN
:
1406 nAction
= ACTION_GOTO_LAST_ROW
;
1412 bool SvxTableController::executeAction( sal_uInt16 nAction
, bool bSelect
, Window
* pWindow
)
1414 ::sdr::table::SdrTableObj
* pTableObj
= dynamic_cast< ::sdr::table::SdrTableObj
* >( mxTableObj
.get() );
1420 case ACTION_GOTO_FIRST_CELL
:
1422 gotoCell( pTableObj
->getFirstCell(), bSelect
, pWindow
, nAction
);
1426 case ACTION_GOTO_LEFT_CELL
:
1428 gotoCell( pTableObj
->getLeftCell( getSelectionEnd(), !bSelect
), bSelect
, pWindow
, nAction
);
1432 case ACTION_GOTO_RIGHT_CELL
:
1434 gotoCell( pTableObj
->getRightCell( getSelectionEnd(), !bSelect
), bSelect
, pWindow
, nAction
);
1438 case ACTION_GOTO_LAST_CELL
:
1440 gotoCell( pTableObj
->getLastCell(), bSelect
, pWindow
, nAction
);
1444 case ACTION_GOTO_FIRST_COLUMN
:
1446 CellPos
aPos( pTableObj
->getFirstCell().mnCol
, getSelectionEnd().mnRow
);
1447 gotoCell( aPos
, bSelect
, pWindow
, nAction
);
1451 case ACTION_GOTO_LAST_COLUMN
:
1453 CellPos
aPos( pTableObj
->getLastCell().mnCol
, getSelectionEnd().mnRow
);
1454 gotoCell( aPos
, bSelect
, pWindow
, nAction
);
1458 case ACTION_GOTO_FIRST_ROW
:
1460 CellPos
aPos( getSelectionEnd().mnCol
, pTableObj
->getFirstCell().mnRow
);
1461 gotoCell( aPos
, bSelect
, pWindow
, nAction
);
1465 case ACTION_GOTO_UP_CELL
:
1467 gotoCell( pTableObj
->getUpCell(getSelectionEnd(), !bSelect
), bSelect
, pWindow
, nAction
);
1471 case ACTION_GOTO_DOWN_CELL
:
1473 gotoCell( pTableObj
->getDownCell(getSelectionEnd(), !bSelect
), bSelect
, pWindow
, nAction
);
1477 case ACTION_GOTO_LAST_ROW
:
1479 CellPos
aPos( getSelectionEnd().mnCol
, pTableObj
->getLastCell().mnRow
);
1480 gotoCell( aPos
, bSelect
, pWindow
, nAction
);
1484 case ACTION_EDIT_CELL
:
1485 EditCell( getSelectionStart(), pWindow
, 0, nAction
);
1488 case ACTION_STOP_TEXT_EDIT
:
1492 case ACTION_REMOVE_SELECTION
:
1496 case ACTION_START_SELECTION
:
1497 StartSelection( getSelectionStart() );
1503 gotoCell( pTableObj
->getPreviousCell( getSelectionEnd(), true ), false, pWindow
, nAction
);
1506 CellPos
aSelectionEnd( getSelectionEnd() );
1507 CellPos
aNextCell( pTableObj
->getNextCell( aSelectionEnd
, true ) );
1508 if( aSelectionEnd
== aNextCell
)
1510 onInsert( SID_TABLE_INSERT_ROW
, 0 );
1511 aNextCell
= pTableObj
->getNextCell( aSelectionEnd
, true );
1513 gotoCell( aNextCell
, false, pWindow
, nAction
);
1519 return nAction
!= ACTION_HANDLED_BY_VIEW
;
1522 // --------------------------------------------------------------------
1524 void SvxTableController::gotoCell( const CellPos
& rPos
, bool bSelect
, Window
* pWindow
, sal_uInt16 nAction
)
1526 if( mxTableObj
.is() && static_cast<SdrTableObj
*>(mxTableObj
.get())->IsTextEditActive() )
1527 mpView
->SdrEndTextEdit(sal_True
);
1531 maCursorLastPos
= rPos
;
1532 if( mxTableObj
.is() )
1533 static_cast< SdrTableObj
* >( mxTableObj
.get() )->setActiveCell( rPos
);
1535 if( !mbCellSelectionMode
)
1537 setSelectedCells( maCursorFirstPos
, rPos
);
1541 UpdateSelection( rPos
);
1547 EditCell( rPos
, pWindow
, 0, nAction
);
1551 // --------------------------------------------------------------------
1553 const CellPos
& SvxTableController::getSelectionStart()
1555 checkCell( maCursorFirstPos
);
1556 return maCursorFirstPos
;
1559 // --------------------------------------------------------------------
1561 void SvxTableController::setSelectionStart( const CellPos
& rPos
)
1563 maCursorFirstPos
= rPos
;
1566 // --------------------------------------------------------------------
1568 const CellPos
& SvxTableController::getSelectionEnd()
1570 checkCell( maCursorLastPos
);
1571 return maCursorLastPos
;
1574 // --------------------------------------------------------------------
1576 void SvxTableController::MergeRange( sal_Int32 nFirstCol
, sal_Int32 nFirstRow
, sal_Int32 nLastCol
, sal_Int32 nLastRow
)
1578 if( mxTable
.is() ) try
1580 Reference
< XMergeableCellRange
> xRange( mxTable
->createCursorByRange( mxTable
->getCellRangeByPosition( nFirstCol
, nFirstRow
,nLastCol
, nLastRow
) ), UNO_QUERY_THROW
);
1581 if( xRange
->isMergeable() )
1583 const bool bUndo
= mpModel
&& mpModel
->IsUndoEnabled();
1586 mpModel
->BegUndo( ImpGetResStr(STR_TABLE_MERGE
) );
1587 mpModel
->AddUndo( mpModel
->GetSdrUndoFactory().CreateUndoGeoObject(*mxTableObj
.get()) );
1598 DBG_ASSERT( false, "sdr::table::SvxTableController::MergeRange(), exception caught!" );
1604 // --------------------------------------------------------------------
1606 void SvxTableController::checkCell( CellPos
& rPos
)
1608 if( mxTable
.is() ) try
1610 if( rPos
.mnCol
>= mxTable
->getColumnCount() )
1611 rPos
.mnCol
= mxTable
->getColumnCount()-1;
1613 if( rPos
.mnRow
>= mxTable
->getRowCount() )
1614 rPos
.mnRow
= mxTable
->getRowCount()-1;
1618 OSL_FAIL("sdr::table::SvxTableController::checkCell(), exception caught!" );
1622 // --------------------------------------------------------------------
1624 void SvxTableController::findMergeOrigin( CellPos
& rPos
)
1626 if( mxTable
.is() ) try
1628 Reference
< XMergeableCell
> xCell( mxTable
->getCellByPosition( rPos
.mnCol
, rPos
.mnRow
), UNO_QUERY_THROW
);
1629 if( xCell
.is() && xCell
->isMerged() )
1631 ::findMergeOrigin( mxTable
, rPos
.mnCol
, rPos
.mnRow
, rPos
.mnCol
, rPos
.mnRow
);
1636 OSL_FAIL("sdr::table::SvxTableController::findMergeOrigin(), exception caught!" );
1640 // --------------------------------------------------------------------
1642 void SvxTableController::EditCell( const CellPos
& rPos
, ::Window
* pWindow
, const awt::MouseEvent
* pMouseEvent
/*= 0*/, sal_uInt16 nAction
/*= ACTION_NONE */ )
1644 SdrPageView
* pPV
= mpView
->GetSdrPageView();
1646 ::sdr::table::SdrTableObj
* pTableObj
= dynamic_cast< ::sdr::table::SdrTableObj
* >( mxTableObj
.get() );
1647 if( pTableObj
&& pTableObj
->GetPage() == pPV
->GetPage() )
1649 bool bEmptyOutliner
= false;
1651 if(!pTableObj
->GetOutlinerParaObject() && mpView
->GetTextEditOutliner())
1653 ::Outliner
* pOutl
= mpView
->GetTextEditOutliner();
1654 sal_uIntPtr nParaAnz
= pOutl
->GetParagraphCount();
1655 Paragraph
* p1stPara
= pOutl
->GetParagraph( 0 );
1657 if(nParaAnz
==1 && p1stPara
)
1659 // Bei nur einem Pararaph
1660 if (pOutl
->GetText(p1stPara
).Len() == 0)
1662 bEmptyOutliner
= true;
1667 CellPos
aPos( rPos
);
1668 findMergeOrigin( aPos
);
1670 if( pTableObj
!= mpView
->GetTextEditObject() || bEmptyOutliner
|| !pTableObj
->IsTextEditActive( aPos
) )
1672 if( pTableObj
->IsTextEditActive() )
1673 mpView
->SdrEndTextEdit(sal_True
);
1675 pTableObj
->setActiveCell( aPos
);
1677 // create new outliner, owner will be the SdrObjEditView
1678 SdrOutliner
* pOutl
= SdrMakeOutliner( OUTLINERMODE_OUTLINEOBJECT
, mpModel
);
1679 if( pTableObj
->IsVerticalWriting() )
1680 pOutl
->SetVertical( sal_True
);
1682 if(mpView
->SdrBeginTextEdit(pTableObj
, pPV
, pWindow
, sal_True
, pOutl
))
1684 maCursorLastPos
= maCursorFirstPos
= rPos
;
1686 OutlinerView
* pOLV
= mpView
->GetTextEditOutlinerView();
1692 ::MouseEvent
aMEvt( *pMouseEvent
);
1695 SdrHitKind eHit
= mpView
->PickAnything(aMEvt
, SDRMOUSEBUTTONDOWN
, aVEvt
);
1697 if (eHit
== SDRHIT_TEXTEDIT
)
1700 pOLV
->MouseButtonDown(aMEvt
);
1701 pOLV
->MouseMove(aMEvt
);
1702 pOLV
->MouseButtonUp(aMEvt
);
1703 // pOLV->MouseButtonDown(aMEvt);
1708 nAction
= ACTION_GOTO_LEFT_CELL
;
1714 // Move cursor to end of text
1715 ESelection aNewSelection
;
1717 const WritingMode eMode
= pTableObj
->GetWritingMode();
1718 if( ((nAction
== ACTION_GOTO_LEFT_CELL
) || (nAction
== ACTION_GOTO_RIGHT_CELL
)) && (eMode
!= WritingMode_TB_RL
) )
1720 const bool bLast
= ((nAction
== ACTION_GOTO_LEFT_CELL
) && (eMode
== WritingMode_LR_TB
)) ||
1721 ((nAction
== ACTION_GOTO_RIGHT_CELL
) && (eMode
== WritingMode_RL_TB
));
1724 aNewSelection
= ESelection(EE_PARA_NOT_FOUND
, EE_INDEX_NOT_FOUND
, EE_PARA_NOT_FOUND
, EE_INDEX_NOT_FOUND
);
1726 pOLV
->SetSelection(aNewSelection
);
1733 // --------------------------------------------------------------------
1735 bool SvxTableController::StopTextEdit()
1737 if(mpView
->IsTextEdit())
1739 mpView
->SdrEndTextEdit();
1740 mpView
->SetCurrentObj(OBJ_TABLE
);
1741 mpView
->SetEditMode(SDREDITMODE_EDIT
);
1750 // --------------------------------------------------------------------
1752 void SvxTableController::getSelectedCells( CellPos
& rFirst
, CellPos
& rLast
)
1754 if( mbCellSelectionMode
)
1756 checkCell( maCursorFirstPos
);
1757 checkCell( maCursorLastPos
);
1759 rFirst
.mnCol
= std::min( maCursorFirstPos
.mnCol
, maCursorLastPos
.mnCol
);
1760 rFirst
.mnRow
= std::min( maCursorFirstPos
.mnRow
, maCursorLastPos
.mnRow
);
1761 rLast
.mnCol
= std::max( maCursorFirstPos
.mnCol
, maCursorLastPos
.mnCol
);
1762 rLast
.mnRow
= std::max( maCursorFirstPos
.mnRow
, maCursorLastPos
.mnRow
);
1765 if( mxTable
.is() ) do
1768 for( sal_Int32 nRow
= rFirst
.mnRow
; nRow
<= rLast
.mnRow
&& !bExt
; nRow
++ )
1770 for( sal_Int32 nCol
= rFirst
.mnCol
; nCol
<= rLast
.mnCol
&& !bExt
; nCol
++ )
1772 Reference
< XMergeableCell
> xCell( mxTable
->getCellByPosition( nCol
, nRow
), UNO_QUERY
);
1776 if( xCell
->isMerged() )
1778 CellPos
aPos( nCol
, nRow
);
1779 findMergeOrigin( aPos
);
1780 if( (aPos
.mnCol
< rFirst
.mnCol
) || (aPos
.mnRow
< rFirst
.mnRow
) )
1782 rFirst
.mnCol
= std::min( rFirst
.mnCol
, aPos
.mnCol
);
1783 rFirst
.mnRow
= std::min( rFirst
.mnRow
, aPos
.mnRow
);
1789 if( ((nCol
+ xCell
->getColumnSpan() - 1) > rLast
.mnCol
) || (nRow
+ xCell
->getRowSpan() - 1 ) > rLast
.mnRow
)
1791 rLast
.mnCol
= std::max( rLast
.mnCol
, nCol
+ xCell
->getColumnSpan() - 1 );
1792 rLast
.mnRow
= std::max( rLast
.mnRow
, nRow
+ xCell
->getRowSpan() - 1 );
1801 else if( mpView
&& mpView
->IsTextEdit() )
1803 rFirst
= getSelectionStart();
1804 findMergeOrigin( rFirst
);
1809 Reference
< XMergeableCell
> xCell( mxTable
->getCellByPosition( rLast
.mnCol
, rLast
.mnRow
), UNO_QUERY
);
1812 rLast
.mnCol
+= xCell
->getColumnSpan() - 1;
1813 rLast
.mnRow
+= xCell
->getRowSpan() - 1;
1823 rLast
.mnRow
= mxTable
->getRowCount()-1;
1824 rLast
.mnCol
= mxTable
->getColumnCount()-1;
1834 // --------------------------------------------------------------------
1836 void SvxTableController::StartSelection( const CellPos
& rPos
)
1839 mbCellSelectionMode
= true;
1840 maCursorLastPos
= maCursorFirstPos
= rPos
;
1841 mpView
->MarkListHasChanged();
1844 // --------------------------------------------------------------------
1846 void SvxTableController::setSelectedCells( const CellPos
& rStart
, const CellPos
& rEnd
)
1849 mbCellSelectionMode
= true;
1850 maCursorFirstPos
= rStart
;
1851 UpdateSelection( rEnd
);
1854 // --------------------------------------------------------------------
1856 void SvxTableController::UpdateSelection( const CellPos
& rPos
)
1858 maCursorLastPos
= rPos
;
1859 mpView
->MarkListHasChanged();
1862 // --------------------------------------------------------------------
1864 void SvxTableController::clearSelection()
1869 // --------------------------------------------------------------------
1871 void SvxTableController::selectAll()
1875 CellPos aPos1
, aPos2( mxTable
->getColumnCount()-1, mxTable
->getRowCount()-1 );
1876 if( (aPos2
.mnCol
>= 0) && (aPos2
.mnRow
>= 0) )
1878 setSelectedCells( aPos1
, aPos2
);
1883 // --------------------------------------------------------------------
1885 void SvxTableController::RemoveSelection()
1887 if( mbCellSelectionMode
)
1889 mbCellSelectionMode
= false;
1890 mpView
->MarkListHasChanged();
1894 // --------------------------------------------------------------------
1896 void SvxTableController::onTableModified()
1898 if( mnUpdateEvent
== 0 )
1899 mnUpdateEvent
= Application::PostUserEvent( LINK( this, SvxTableController
, UpdateHdl
) );
1901 // --------------------------------------------------------------------
1903 void SvxTableController::updateSelectionOverlay()
1905 destroySelectionOverlay();
1906 if( mbCellSelectionMode
)
1908 ::sdr::table::SdrTableObj
* pTableObj
= dynamic_cast< ::sdr::table::SdrTableObj
* >( mxTableObj
.get() );
1911 sdr::overlay::OverlayObjectCell::RangeVector aRanges
;
1914 CellPos aStart
,aEnd
;
1915 getSelectedCells( aStart
, aEnd
);
1916 pTableObj
->getCellBounds( aStart
, aRect
);
1918 basegfx::B2DRange
a2DRange( basegfx::B2DPoint(aRect
.Left(), aRect
.Top()) );
1919 a2DRange
.expand( basegfx::B2DPoint(aRect
.Right(), aRect
.Bottom()) );
1921 findMergeOrigin( aEnd
);
1922 pTableObj
->getCellBounds( aEnd
, aRect
);
1923 a2DRange
.expand( basegfx::B2DPoint(aRect
.Left(), aRect
.Top()) );
1924 a2DRange
.expand( basegfx::B2DPoint(aRect
.Right(), aRect
.Bottom()) );
1925 aRanges
.push_back( a2DRange
);
1927 ::Color
aHighlight( COL_BLUE
);
1928 OutputDevice
* pOutDev
= mpView
->GetFirstOutputDevice();
1930 aHighlight
= pOutDev
->GetSettings().GetStyleSettings().GetHighlightColor();
1932 const sal_uInt32 nCount
= mpView
->PaintWindowCount();
1933 for( sal_uInt32 nIndex
= 0; nIndex
< nCount
; nIndex
++ )
1935 SdrPaintWindow
* pPaintWindow
= mpView
->GetPaintWindow(nIndex
);
1938 rtl::Reference
< ::sdr::overlay::OverlayManager
> xOverlayManager
= pPaintWindow
->GetOverlayManager();
1939 if( xOverlayManager
.is() )
1941 // sdr::overlay::CellOverlayType eType = sdr::overlay::CELL_OVERLAY_INVERT;
1942 sdr::overlay::CellOverlayType eType
= sdr::overlay::CELL_OVERLAY_TRANSPARENT
;
1944 sdr::overlay::OverlayObjectCell
* pOverlay
= new sdr::overlay::OverlayObjectCell( eType
, aHighlight
, aRanges
);
1946 xOverlayManager
->add(*pOverlay
);
1947 mpSelectionOverlay
= new ::sdr::overlay::OverlayObjectList
;
1948 mpSelectionOverlay
->append(*pOverlay
);
1956 // --------------------------------------------------------------------
1958 void SvxTableController::destroySelectionOverlay()
1960 if( mpSelectionOverlay
)
1962 delete mpSelectionOverlay
;
1963 mpSelectionOverlay
= 0;
1967 // --------------------------------------------------------------------
1969 void SvxTableController::MergeAttrFromSelectedCells(SfxItemSet
& rAttr
, bool bOnlyHardAttr
) const
1973 CellPos aStart
, aEnd
;
1974 const_cast<SvxTableController
&>(*this).getSelectedCells( aStart
, aEnd
);
1976 for( sal_Int32 nRow
= aStart
.mnRow
; nRow
<= aEnd
.mnRow
; nRow
++ )
1978 for( sal_Int32 nCol
= aStart
.mnCol
; nCol
<= aEnd
.mnCol
; nCol
++ )
1980 CellRef
xCell( dynamic_cast< Cell
* >( mxTable
->getCellByPosition( nCol
, nRow
).get() ) );
1981 if( xCell
.is() && !xCell
->isMerged() )
1983 const SfxItemSet
& rSet
= xCell
->GetItemSet();
1984 SfxWhichIter
aIter(rSet
);
1985 sal_uInt16
nWhich(aIter
.FirstWhich());
1990 if(SFX_ITEM_DONTCARE
== rSet
.GetItemState(nWhich
, sal_False
))
1991 rAttr
.InvalidateItem(nWhich
);
1993 rAttr
.MergeValue(rSet
.Get(nWhich
), sal_True
);
1995 else if(SFX_ITEM_SET
== rSet
.GetItemState(nWhich
, sal_False
))
1997 const SfxPoolItem
& rItem
= rSet
.Get(nWhich
);
1998 rAttr
.MergeValue(rItem
, sal_True
);
2001 nWhich
= aIter
.NextWhich();
2008 if( mpView
->IsTextEdit() )
2013 // --------------------------------------------------------------------
2015 const sal_uInt16 CELL_BEFORE
= 0x0001;
2016 const sal_uInt16 CELL_LEFT
= 0x0002;
2017 const sal_uInt16 CELL_RIGHT
= 0x0004;
2018 const sal_uInt16 CELL_AFTER
= 0x0008;
2020 const sal_uInt16 CELL_UPPER
= 0x0010;
2021 const sal_uInt16 CELL_TOP
= 0x0020;
2022 const sal_uInt16 CELL_BOTTOM
= 0x0040;
2023 const sal_uInt16 CELL_LOWER
= 0x0080;
2025 // --------------------------------------------------------------------
2027 static void ImplSetLinePreserveColor( SvxBoxItem
& rNewFrame
, const SvxBorderLine
* pNew
, sal_uInt16 nLine
)
2031 const SvxBorderLine
* pOld
= rNewFrame
.GetLine(nLine
);
2034 SvxBorderLine
aNewLine( *pNew
);
2035 aNewLine
.SetColor( pOld
->GetColor() );
2036 rNewFrame
.SetLine( &aNewLine
, nLine
);
2040 rNewFrame
.SetLine( pNew
, nLine
);
2043 // --------------------------------------------------------------------
2045 static void ImplApplyBoxItem( sal_uInt16 nCellFlags
, const SvxBoxItem
* pBoxItem
, const SvxBoxInfoItem
* pBoxInfoItem
, SvxBoxItem
& rNewFrame
)
2047 if( (nCellFlags
& (CELL_BEFORE
|CELL_AFTER
|CELL_UPPER
|CELL_LOWER
)) != 0 )
2049 // current cell is outside the selection
2051 if( (nCellFlags
& ( CELL_BEFORE
|CELL_AFTER
)) == 0 ) // check if its not nw or ne corner
2053 if( nCellFlags
& CELL_UPPER
)
2055 if( pBoxInfoItem
->IsValid(VALID_TOP
) )
2056 rNewFrame
.SetLine(0, BOX_LINE_BOTTOM
);
2058 else if( nCellFlags
& CELL_LOWER
)
2060 if( pBoxInfoItem
->IsValid(VALID_BOTTOM
) )
2061 rNewFrame
.SetLine( 0, BOX_LINE_TOP
);
2064 else if( (nCellFlags
& ( CELL_UPPER
|CELL_LOWER
)) == 0 ) // check if its not sw or se corner
2066 if( nCellFlags
& CELL_BEFORE
)
2068 if( pBoxInfoItem
->IsValid(VALID_LEFT
) )
2069 rNewFrame
.SetLine( 0, BOX_LINE_RIGHT
);
2071 else if( nCellFlags
& CELL_AFTER
)
2073 if( pBoxInfoItem
->IsValid(VALID_RIGHT
) )
2074 rNewFrame
.SetLine( 0, BOX_LINE_LEFT
);
2080 // current cell is inside the selection
2082 if( (nCellFlags
& CELL_LEFT
) ? pBoxInfoItem
->IsValid(VALID_LEFT
) : pBoxInfoItem
->IsValid(VALID_VERT
) )
2083 rNewFrame
.SetLine( (nCellFlags
& CELL_LEFT
) ? pBoxItem
->GetLeft() : pBoxInfoItem
->GetVert(), BOX_LINE_LEFT
);
2085 if( (nCellFlags
& CELL_RIGHT
) ? pBoxInfoItem
->IsValid(VALID_RIGHT
) : pBoxInfoItem
->IsValid(VALID_VERT
) )
2086 rNewFrame
.SetLine( (nCellFlags
& CELL_RIGHT
) ? pBoxItem
->GetRight() : pBoxInfoItem
->GetVert(), BOX_LINE_RIGHT
);
2088 if( (nCellFlags
& CELL_TOP
) ? pBoxInfoItem
->IsValid(VALID_TOP
) : pBoxInfoItem
->IsValid(VALID_HORI
) )
2089 rNewFrame
.SetLine( (nCellFlags
& CELL_TOP
) ? pBoxItem
->GetTop() : pBoxInfoItem
->GetHori(), BOX_LINE_TOP
);
2091 if( (nCellFlags
& CELL_BOTTOM
) ? pBoxInfoItem
->IsValid(VALID_BOTTOM
) : pBoxInfoItem
->IsValid(VALID_HORI
) )
2092 rNewFrame
.SetLine( (nCellFlags
& CELL_BOTTOM
) ? pBoxItem
->GetBottom() : pBoxInfoItem
->GetHori(), BOX_LINE_BOTTOM
);
2094 // apply distance to borders
2095 if( pBoxInfoItem
->IsValid( VALID_DISTANCE
) )
2096 for( sal_uInt16 nLine
= 0; nLine
< 4; ++nLine
)
2097 rNewFrame
.SetDistance( pBoxItem
->GetDistance( nLine
), nLine
);
2101 // --------------------------------------------------------------------
2103 static void ImplSetLineColor( SvxBoxItem
& rNewFrame
, sal_uInt16 nLine
, const Color
& rColor
)
2105 const SvxBorderLine
* pSourceLine
= rNewFrame
.GetLine( nLine
);
2108 SvxBorderLine
aLine( *pSourceLine
);
2109 aLine
.SetColor( rColor
);
2110 rNewFrame
.SetLine( &aLine
, nLine
);
2114 // --------------------------------------------------------------------
2116 static void ImplApplyLineColorItem( sal_uInt16 nCellFlags
, const SvxColorItem
* pLineColorItem
, SvxBoxItem
& rNewFrame
)
2118 const Color
aColor( pLineColorItem
->GetValue() );
2120 if( (nCellFlags
& (CELL_LOWER
|CELL_BEFORE
|CELL_AFTER
)) == 0 )
2121 ImplSetLineColor( rNewFrame
, BOX_LINE_BOTTOM
, aColor
);
2123 if( (nCellFlags
& (CELL_UPPER
|CELL_BEFORE
|CELL_AFTER
)) == 0 )
2124 ImplSetLineColor( rNewFrame
, BOX_LINE_TOP
, aColor
);
2126 if( (nCellFlags
& (CELL_UPPER
|CELL_LOWER
|CELL_AFTER
)) == 0 )
2127 ImplSetLineColor( rNewFrame
, BOX_LINE_RIGHT
, aColor
);
2129 if( (nCellFlags
& (CELL_UPPER
|CELL_LOWER
|CELL_BEFORE
)) == 0 )
2130 ImplSetLineColor( rNewFrame
, BOX_LINE_LEFT
, aColor
);
2133 // --------------------------------------------------------------------
2135 static void ImplApplyBorderLineItem( sal_uInt16 nCellFlags
, const SvxBorderLine
* pBorderLineItem
, SvxBoxItem
& rNewFrame
)
2137 if( (nCellFlags
& ( CELL_BEFORE
|CELL_AFTER
|CELL_UPPER
|CELL_LOWER
)) != 0 )
2139 if( (nCellFlags
& ( CELL_BEFORE
|CELL_AFTER
)) == 0 ) // check if its not nw or ne corner
2141 if( nCellFlags
& CELL_UPPER
)
2143 if( rNewFrame
.GetBottom() )
2144 ImplSetLinePreserveColor( rNewFrame
, pBorderLineItem
, BOX_LINE_BOTTOM
);
2146 else if( nCellFlags
& CELL_LOWER
)
2148 if( rNewFrame
.GetTop() )
2149 ImplSetLinePreserveColor( rNewFrame
, pBorderLineItem
, BOX_LINE_TOP
);
2152 else if( (nCellFlags
& ( CELL_UPPER
|CELL_LOWER
)) == 0 ) // check if its not sw or se corner
2154 if( nCellFlags
& CELL_BEFORE
)
2156 if( rNewFrame
.GetRight() )
2157 ImplSetLinePreserveColor( rNewFrame
, pBorderLineItem
, BOX_LINE_RIGHT
);
2159 else if( nCellFlags
& CELL_AFTER
)
2161 if( rNewFrame
.GetLeft() )
2162 ImplSetLinePreserveColor( rNewFrame
, pBorderLineItem
, BOX_LINE_LEFT
);
2168 if( rNewFrame
.GetBottom() )
2169 ImplSetLinePreserveColor( rNewFrame
, pBorderLineItem
, BOX_LINE_BOTTOM
);
2170 if( rNewFrame
.GetTop() )
2171 ImplSetLinePreserveColor( rNewFrame
, pBorderLineItem
, BOX_LINE_TOP
);
2172 if( rNewFrame
.GetRight() )
2173 ImplSetLinePreserveColor( rNewFrame
, pBorderLineItem
, BOX_LINE_RIGHT
);
2174 if( rNewFrame
.GetLeft() )
2175 ImplSetLinePreserveColor( rNewFrame
, pBorderLineItem
, BOX_LINE_LEFT
);
2179 // --------------------------------------------------------------------
2181 void SvxTableController::ApplyBorderAttr( const SfxItemSet
& rAttr
)
2185 const sal_Int32 nRowCount
= mxTable
->getRowCount();
2186 const sal_Int32 nColCount
= mxTable
->getColumnCount();
2187 if( nRowCount
&& nColCount
)
2189 const SvxBoxItem
* pBoxItem
= 0;
2190 if(SFX_ITEM_SET
== rAttr
.GetItemState(SDRATTR_TABLE_BORDER
, sal_False
) )
2191 pBoxItem
= dynamic_cast< const SvxBoxItem
* >( &rAttr
.Get( SDRATTR_TABLE_BORDER
) );
2193 const SvxBoxInfoItem
* pBoxInfoItem
= 0;
2194 if(SFX_ITEM_SET
== rAttr
.GetItemState(SDRATTR_TABLE_BORDER_INNER
, sal_False
) )
2195 pBoxInfoItem
= dynamic_cast< const SvxBoxInfoItem
* >( &rAttr
.Get( SDRATTR_TABLE_BORDER_INNER
) );
2197 const SvxColorItem
* pLineColorItem
= 0;
2198 if(SFX_ITEM_SET
== rAttr
.GetItemState(SID_FRAME_LINECOLOR
, sal_False
) )
2199 pLineColorItem
= dynamic_cast< const SvxColorItem
* >( &rAttr
.Get( SID_FRAME_LINECOLOR
) );
2201 const SvxBorderLine
* pBorderLineItem
= 0;
2202 if(SFX_ITEM_SET
== rAttr
.GetItemState(SID_FRAME_LINESTYLE
, sal_False
) )
2203 pBorderLineItem
= ((const SvxLineItem
&)rAttr
.Get( SID_FRAME_LINESTYLE
)).GetLine();
2205 if( pBoxInfoItem
&& !pBoxItem
)
2207 const static SvxBoxItem
gaEmptyBoxItem( SDRATTR_TABLE_BORDER
);
2208 pBoxItem
= &gaEmptyBoxItem
;
2210 else if( pBoxItem
&& !pBoxInfoItem
)
2212 const static SvxBoxInfoItem
gaEmptyBoxInfoItem( SDRATTR_TABLE_BORDER_INNER
);
2213 pBoxInfoItem
= &gaEmptyBoxInfoItem
;
2216 CellPos aStart
, aEnd
;
2217 getSelectedCells( aStart
, aEnd
);
2219 const sal_Int32 nLastRow
= std::min( aEnd
.mnRow
+ 2, nRowCount
);
2220 const sal_Int32 nLastCol
= std::min( aEnd
.mnCol
+ 2, nColCount
);
2222 for( sal_Int32 nRow
= std::max( aStart
.mnRow
- 1, (sal_Int32
)0 ); nRow
< nLastRow
; nRow
++ )
2224 sal_uInt16 nRowFlags
= 0;
2225 nRowFlags
|= (nRow
== aStart
.mnRow
) ? CELL_TOP
: 0;
2226 nRowFlags
|= (nRow
== aEnd
.mnRow
) ? CELL_BOTTOM
: 0;
2227 nRowFlags
|= (nRow
< aStart
.mnRow
) ? CELL_UPPER
: 0;
2228 nRowFlags
|= (nRow
> aEnd
.mnRow
) ? CELL_LOWER
: 0;
2230 for( sal_Int32 nCol
= std::max( aStart
.mnCol
- 1, (sal_Int32
)0 ); nCol
< nLastCol
; nCol
++ )
2232 CellRef
xCell( dynamic_cast< Cell
* >( mxTable
->getCellByPosition( nCol
, nRow
).get() ) );
2236 const SfxItemSet
& rSet
= xCell
->GetItemSet();
2237 const SvxBoxItem
* pOldOuter
= (const SvxBoxItem
*) &rSet
.Get( SDRATTR_TABLE_BORDER
);
2239 SvxBoxItem
aNewFrame( *pOldOuter
);
2241 sal_uInt16 nCellFlags
= nRowFlags
;
2242 nCellFlags
|= (nCol
== aStart
.mnCol
) ? CELL_LEFT
: 0;
2243 nCellFlags
|= (nCol
== aEnd
.mnCol
) ? CELL_RIGHT
: 0;
2244 nCellFlags
|= (nCol
< aStart
.mnCol
) ? CELL_BEFORE
: 0;
2245 nCellFlags
|= (nCol
> aEnd
.mnCol
) ? CELL_AFTER
: 0;
2247 if( pBoxItem
&& pBoxInfoItem
)
2248 ImplApplyBoxItem( nCellFlags
, pBoxItem
, pBoxInfoItem
, aNewFrame
);
2250 if( pLineColorItem
)
2251 ImplApplyLineColorItem( nCellFlags
, pLineColorItem
, aNewFrame
);
2253 if( pBorderLineItem
)
2254 ImplApplyBorderLineItem( nCellFlags
, pBorderLineItem
, aNewFrame
);
2256 if (aNewFrame
!= *pOldOuter
)
2258 SfxItemSet
aAttr(*rSet
.GetPool(), rSet
.GetRanges());
2259 aAttr
.Put(aNewFrame
);
2260 xCell
->SetMergedItemSetAndBroadcast( aAttr
, false );
2268 // --------------------------------------------------------------------
2270 void SvxTableController::UpdateTableShape()
2272 SdrObject
* pTableObj
= mxTableObj
.get();
2275 pTableObj
->ActionChanged();
2276 pTableObj
->BroadcastObjectChange();
2278 updateSelectionOverlay();
2282 // --------------------------------------------------------------------
2284 void SvxTableController::SetAttrToSelectedCells(const SfxItemSet
& rAttr
, bool bReplaceAll
)
2288 const bool bUndo
= mpModel
&& mpModel
->IsUndoEnabled();
2291 mpModel
->BegUndo( ImpGetResStr(STR_TABLE_NUMFORMAT
) );
2293 CellPos aStart
, aEnd
;
2294 getSelectedCells( aStart
, aEnd
);
2296 SfxItemSet
aAttr(*rAttr
.GetPool(), rAttr
.GetRanges());
2297 aAttr
.Put(rAttr
, sal_True
);
2299 const bool bFrame
= (rAttr
.GetItemState( SDRATTR_TABLE_BORDER
) == SFX_ITEM_SET
) || (rAttr
.GetItemState( SDRATTR_TABLE_BORDER_INNER
) == SFX_ITEM_SET
);
2303 aAttr
.ClearItem( SDRATTR_TABLE_BORDER
);
2304 aAttr
.ClearItem( SDRATTR_TABLE_BORDER_INNER
);
2307 for( sal_Int32 nRow
= aStart
.mnRow
; nRow
<= aEnd
.mnRow
; nRow
++ )
2309 for( sal_Int32 nCol
= aStart
.mnCol
; nCol
<= aEnd
.mnCol
; nCol
++ )
2311 CellRef
xCell( dynamic_cast< Cell
* >( mxTable
->getCellByPosition( nCol
, nRow
).get() ) );
2316 xCell
->SetMergedItemSetAndBroadcast(aAttr
, bReplaceAll
);
2323 ApplyBorderAttr( rAttr
);
2334 // --------------------------------------------------------------------
2336 bool SvxTableController::GetAttributes(SfxItemSet
& rTargetSet
, bool bOnlyHardAttr
) const
2338 if( mxTableObj
.is() && hasSelectedCells() )
2340 MergeAttrFromSelectedCells( rTargetSet
, bOnlyHardAttr
);
2342 if( mpView
->IsTextEdit() )
2344 if( mxTableObj
->GetOutlinerParaObject() )
2345 rTargetSet
.Put( SvxScriptTypeItem( mxTableObj
->GetOutlinerParaObject()->GetTextObject().GetScriptType() ) );
2347 OutlinerView
* pTextEditOutlinerView
= mpView
->GetTextEditOutlinerView();
2348 if(pTextEditOutlinerView
)
2350 // FALSE= InvalidItems nicht al Default, sondern als "Loecher" betrachten
2351 rTargetSet
.Put(pTextEditOutlinerView
->GetAttribs(), sal_False
);
2352 rTargetSet
.Put( SvxScriptTypeItem( pTextEditOutlinerView
->GetSelectedScriptType() ), sal_False
);
2364 // --------------------------------------------------------------------
2366 bool SvxTableController::SetAttributes(const SfxItemSet
& rSet
, bool bReplaceAll
)
2368 if( mbCellSelectionMode
|| mpView
->IsTextEdit() )
2370 SetAttrToSelectedCells( rSet
, bReplaceAll
);
2376 // --------------------------------------------------------------------
2378 bool SvxTableController::GetMarkedObjModel( SdrPage
* pNewPage
)
2380 if( mxTableObj
.is() && mbCellSelectionMode
&& pNewPage
) try
2382 ::sdr::table::SdrTableObj
& rTableObj
= *static_cast< ::sdr::table::SdrTableObj
* >( mxTableObj
.get() );
2384 CellPos aStart
, aEnd
;
2385 getSelectedCells( aStart
, aEnd
);
2387 SdrTableObj
* pNewTableObj
= rTableObj
.CloneRange( aStart
, aEnd
);
2389 pNewTableObj
->SetPage( pNewPage
);
2390 pNewTableObj
->SetModel( pNewPage
->GetModel() );
2392 SdrInsertReason
aReason(SDRREASON_VIEWCALL
);
2393 pNewPage
->InsertObject(pNewTableObj
,CONTAINER_APPEND
,&aReason
);
2399 OSL_FAIL( "svx::SvxTableController::GetMarkedObjModel(), exception caught!" );
2404 // --------------------------------------------------------------------
2406 bool SvxTableController::PasteObjModel( const SdrModel
& rModel
)
2408 if( mxTableObj
.is() && mpView
&& (rModel
.GetPageCount() >= 1) )
2410 const SdrPage
* pPastePage
= rModel
.GetPage(0);
2411 if( pPastePage
&& pPastePage
->GetObjCount() == 1 )
2413 SdrTableObj
* pPasteTableObj
= dynamic_cast< SdrTableObj
* >( pPastePage
->GetObj(0) );
2414 if( pPasteTableObj
)
2416 return PasteObject( pPasteTableObj
);
2424 // --------------------------------------------------------------------
2426 bool SvxTableController::PasteObject( SdrTableObj
* pPasteTableObj
)
2428 if( !pPasteTableObj
)
2431 Reference
< XTable
> xPasteTable( pPasteTableObj
->getTable() );
2432 if( !xPasteTable
.is() )
2438 sal_Int32 nPasteColumns
= xPasteTable
->getColumnCount();
2439 sal_Int32 nPasteRows
= xPasteTable
->getRowCount();
2441 CellPos aStart
, aEnd
;
2442 getSelectedCells( aStart
, aEnd
);
2444 if( mpView
->IsTextEdit() )
2445 mpView
->SdrEndTextEdit(sal_True
);
2447 sal_Int32 nColumns
= mxTable
->getColumnCount();
2448 sal_Int32 nRows
= mxTable
->getRowCount();
2450 const sal_Int32 nMissing
= nPasteRows
- ( nRows
- aStart
.mnRow
);
2453 Reference
< XTableRows
> xRows( mxTable
->getRows() );
2454 xRows
->insertByIndex( nRows
, nMissing
);
2455 nRows
= mxTable
->getRowCount();
2458 nPasteRows
= std::min( nPasteRows
, nRows
- aStart
.mnRow
);
2459 nPasteColumns
= std::min( nPasteColumns
, nColumns
- aStart
.mnCol
);
2461 // copy cell contents
2462 for( sal_Int32 nRow
= 0; nRow
< nPasteRows
; ++nRow
)
2464 for( sal_Int32 nCol
= 0; nCol
< nPasteColumns
; ++nCol
)
2466 CellRef
xTargetCell( dynamic_cast< Cell
* >( mxTable
->getCellByPosition( aStart
.mnCol
+ nCol
, aStart
.mnRow
+ nRow
).get() ) );
2467 if( xTargetCell
.is() && !xTargetCell
->isMerged() )
2469 xTargetCell
->AddUndo();
2470 xTargetCell
->cloneFrom( dynamic_cast< Cell
* >( xPasteTable
->getCellByPosition( nCol
, nRow
).get() ) );
2471 nCol
+= xTargetCell
->getColumnSpan() - 1;
2481 bool SvxTableController::TakeFormatPaintBrush( boost::shared_ptr
< SfxItemSet
>& /*rFormatSet*/ )
2483 // SdrView::TakeFormatPaintBrush() is enough
2487 bool SvxTableController::ApplyFormatPaintBrush( SfxItemSet
& rFormatSet
, bool bNoCharacterFormats
, bool bNoParagraphFormats
)
2489 if( mbCellSelectionMode
)
2491 SdrTextObj
* pTableObj
= dynamic_cast<SdrTextObj
*>( mxTableObj
.get() );
2495 const bool bUndo
= mpModel
&& mpModel
->IsUndoEnabled();
2498 mpModel
->BegUndo( ImpGetResStr(STR_TABLE_NUMFORMAT
) );
2500 CellPos aStart
, aEnd
;
2501 getSelectedCells( aStart
, aEnd
);
2503 SfxItemSet
aAttr(*rFormatSet
.GetPool(), rFormatSet
.GetRanges());
2504 aAttr
.Put(rFormatSet
, sal_True
);
2506 const bool bFrame
= (rFormatSet
.GetItemState( SDRATTR_TABLE_BORDER
) == SFX_ITEM_SET
) || (rFormatSet
.GetItemState( SDRATTR_TABLE_BORDER_INNER
) == SFX_ITEM_SET
);
2510 aAttr
.ClearItem( SDRATTR_TABLE_BORDER
);
2511 aAttr
.ClearItem( SDRATTR_TABLE_BORDER_INNER
);
2514 const sal_uInt16
* pRanges
= rFormatSet
.GetRanges();
2515 bool bTextOnly
= true;
2519 if( (*pRanges
!= EE_PARA_START
) && (*pRanges
!= EE_CHAR_START
) )
2527 const bool bReplaceAll
= false;
2528 for( sal_Int32 nRow
= aStart
.mnRow
; nRow
<= aEnd
.mnRow
; nRow
++ )
2530 for( sal_Int32 nCol
= aStart
.mnCol
; nCol
<= aEnd
.mnCol
; nCol
++ )
2532 CellRef
xCell( dynamic_cast< Cell
* >( mxTable
->getCellByPosition( nCol
, nRow
).get() ) );
2538 xCell
->SetMergedItemSetAndBroadcast(aAttr
, bReplaceAll
);
2540 SdrText
* pText
= static_cast< SdrText
* >( xCell
.get() );
2541 mpView
->ApplyFormatPaintBrushToText( rFormatSet
, *pTableObj
, pText
, bNoCharacterFormats
, bNoParagraphFormats
);
2548 ApplyBorderAttr( rFormatSet
);
2563 // --------------------------------------------------------------------
2565 IMPL_LINK_NOARG(SvxTableController
, UpdateHdl
)
2569 if( mbCellSelectionMode
)
2571 CellPos
aStart( maCursorFirstPos
);
2572 CellPos
aEnd( maCursorLastPos
);
2575 if( aStart
!= maCursorFirstPos
|| aEnd
!= maCursorLastPos
)
2577 setSelectedCells( aStart
, aEnd
);
2580 updateSelectionOverlay();
2587 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */