1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
22 #include <svx/sdr/table/tablecontroller.hxx>
23 #include <tablemodel.hxx>
25 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
26 #include <com/sun/star/container/XIndexAccess.hpp>
28 #include <com/sun/star/beans/XPropertySet.hpp>
29 #include <com/sun/star/table/XMergeableCellRange.hpp>
30 #include <com/sun/star/table/XMergeableCell.hpp>
32 #include <sal/config.h>
34 #include <vcl/svapp.hxx>
35 #include <vcl/settings.hxx>
37 #include <svl/whiter.hxx>
39 #include <sfx2/request.hxx>
41 #include <editeng/scripttypeitem.hxx>
42 #include <svx/svdotable.hxx>
43 #include <svx/sdr/overlay/overlayobjectcell.hxx>
44 #include <svx/sdr/overlay/overlaymanager.hxx>
45 #include <svx/svxids.hrc>
46 #include <editeng/outlobj.hxx>
47 #include <svx/svdoutl.hxx>
48 #include <svx/svdpagv.hxx>
49 #include <svx/svdetc.hxx>
50 #include <editeng/editobj.hxx>
51 #include "editeng/editstat.hxx"
52 #include "editeng/unolingu.hxx"
53 #include "svx/sdrpagewindow.hxx"
54 #include <svx/selectioncontroller.hxx>
55 #include <svx/svdmodel.hxx>
56 #include "svx/sdrpaintwindow.hxx"
57 #include <svx/svxdlg.hxx>
58 #include <editeng/boxitem.hxx>
60 #include <editeng/borderline.hxx>
61 #include <editeng/colritem.hxx>
62 #include "editeng/lineitem.hxx"
63 #include "svx/svdstr.hrc"
64 #include "svdglob.hxx"
65 #include "svx/svdpage.hxx"
66 #include "tableundo.hxx"
67 #include "tablelayouter.hxx"
68 #include <vcl/msgbox.hxx>
69 #include <boost/scoped_ptr.hpp>
71 using ::editeng::SvxBorderLine
;
72 using namespace ::sdr::table
;
73 using namespace ::com::sun::star
;
74 using namespace ::com::sun::star::uno
;
75 using namespace ::com::sun::star::table
;
76 using namespace ::com::sun::star::beans
;
77 using namespace ::com::sun::star::container
;
78 using namespace ::com::sun::star::text
;
79 using namespace ::com::sun::star::style
;
81 namespace sdr
{ namespace table
{
84 // class SvxTableControllerModifyListener
87 class SvxTableControllerModifyListener
: public ::cppu::WeakImplHelper1
< ::com::sun::star::util::XModifyListener
>
90 SvxTableControllerModifyListener( SvxTableController
* pController
)
91 : mpController( pController
) {}
94 virtual void SAL_CALL
modified( const ::com::sun::star::lang::EventObject
& aEvent
) throw (::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
97 virtual void SAL_CALL
disposing( const ::com::sun::star::lang::EventObject
& Source
) throw (::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
99 SvxTableController
* mpController
;
106 void SAL_CALL
SvxTableControllerModifyListener::modified( const ::com::sun::star::lang::EventObject
& ) throw (::com::sun::star::uno::RuntimeException
, std::exception
)
109 mpController
->onTableModified();
116 void SAL_CALL
SvxTableControllerModifyListener::disposing( const ::com::sun::star::lang::EventObject
& ) throw (::com::sun::star::uno::RuntimeException
, std::exception
)
122 // class SvxTableController
125 rtl::Reference
< sdr::SelectionController
> CreateTableController( SdrObjEditView
* pView
, const SdrObject
* pObj
, const rtl::Reference
< sdr::SelectionController
>& xRefController
)
127 return SvxTableController::create( pView
, pObj
, xRefController
);
132 rtl::Reference
< sdr::SelectionController
> SvxTableController::create( SdrObjEditView
* pView
, const SdrObject
* pObj
, const rtl::Reference
< sdr::SelectionController
>& xRefController
)
134 if( xRefController
.is() )
136 SvxTableController
* pController
= dynamic_cast< SvxTableController
* >( xRefController
.get() );
137 if( pController
&& (pController
->mxTableObj
.get() == pObj
) && (pController
->mpView
== pView
) )
138 return xRefController
;
140 return new SvxTableController( pView
, pObj
);
145 SvxTableController::SvxTableController( SdrObjEditView
* pView
, const SdrObject
* pObj
)
146 : mbCellSelectionMode(false)
147 , mbLeftButtonDown(false)
148 , mpSelectionOverlay(0)
149 , mpView( dynamic_cast< SdrView
* >( pView
) )
150 , mxTableObj( dynamic_cast< SdrTableObj
* >( const_cast< SdrObject
* >( pObj
) ) )
155 mpModel
= pObj
->GetModel();
157 if( mxTableObj
.is() )
159 static_cast< const SdrTableObj
* >( pObj
)->getActiveCellPos( maCursorFirstPos
);
160 maCursorLastPos
= maCursorFirstPos
;
162 Reference
< XTable
> xTable( static_cast< const SdrTableObj
* >( pObj
)->getTable() );
165 mxModifyListener
= new SvxTableControllerModifyListener( this );
166 xTable
->addModifyListener( mxModifyListener
);
168 mxTable
.set( dynamic_cast< TableModel
* >( xTable
.get() ) );
175 SvxTableController::~SvxTableController()
179 Application::RemoveUserEvent( mnUpdateEvent
);
182 if( mxModifyListener
.is() && mxTableObj
.get() )
184 Reference
< XTable
> xTable( static_cast< SdrTableObj
* >( mxTableObj
.get() )->getTable() );
187 xTable
->removeModifyListener( mxModifyListener
);
188 mxModifyListener
.clear();
195 const sal_uInt16 ACTION_NONE
= 0;
196 const sal_uInt16 ACTION_GOTO_FIRST_CELL
= 1;
197 const sal_uInt16 ACTION_GOTO_FIRST_COLUMN
= 2;
198 const sal_uInt16 ACTION_GOTO_FIRST_ROW
= 3;
199 const sal_uInt16 ACTION_GOTO_LEFT_CELL
= 4;
200 const sal_uInt16 ACTION_GOTO_UP_CELL
= 5;
201 const sal_uInt16 ACTION_GOTO_RIGHT_CELL
= 6;
202 const sal_uInt16 ACTION_GOTO_DOWN_CELL
= 7;
203 const sal_uInt16 ACTION_GOTO_LAST_CELL
= 8;
204 const sal_uInt16 ACTION_GOTO_LAST_COLUMN
= 9;
205 const sal_uInt16 ACTION_GOTO_LAST_ROW
= 10;
206 const sal_uInt16 ACTION_EDIT_CELL
= 11;
207 const sal_uInt16 ACTION_STOP_TEXT_EDIT
= 12;
208 const sal_uInt16 ACTION_REMOVE_SELECTION
= 13;
209 const sal_uInt16 ACTION_START_SELECTION
= 14;
210 const sal_uInt16 ACTION_HANDLED_BY_VIEW
= 15;
211 const sal_uInt16 ACTION_TAB
= 18;
213 bool SvxTableController::onKeyInput(const KeyEvent
& rKEvt
, Window
* pWindow
)
215 if( !checkTableObject() )
218 // check if we are read only
219 if( mpModel
&& mpModel
->IsReadOnly())
221 switch( rKEvt
.GetKeyCode().GetCode() )
226 case awt::Key::RIGHT
:
234 case awt::Key::ESCAPE
:
238 // tell the view we eat the event, no further processing needed
243 sal_uInt16 nAction
= getKeyboardAction( rKEvt
, pWindow
);
245 return executeAction( nAction
, ( rKEvt
.GetKeyCode().IsShift() ) ? sal_True
: sal_False
, pWindow
);
249 // ::com::sun::star::awt::XMouseClickHandler:
252 bool SvxTableController::onMouseButtonDown(const MouseEvent
& rMEvt
, Window
* pWindow
)
254 if( !pWindow
|| !checkTableObject() )
258 if( !rMEvt
.IsRight() && mpView
->PickAnything(rMEvt
,SDRMOUSEBUTTONDOWN
, aVEvt
) == SDRHIT_HANDLE
)
261 TableHitKind eHit
= static_cast< SdrTableObj
* >(mxTableObj
.get())->CheckTableHit( pWindow
->PixelToLogic(rMEvt
.GetPosPixel()), maMouseDownPos
.mnCol
, maMouseDownPos
.mnRow
, 0 );
263 mbLeftButtonDown
= (rMEvt
.GetClicks() == 1) && rMEvt
.IsLeft();
265 if( eHit
== SDRTABLEHIT_CELL
)
267 StartSelection( maMouseDownPos
);
271 if( rMEvt
.IsRight() && eHit
!= SDRTABLEHIT_NONE
)
272 return true; // right click will become context menu
274 // for cell selection with the mouse remember our first hit
275 if( mbLeftButtonDown
)
279 Point
aPnt(rMEvt
.GetPosPixel());
281 aPnt
=pWindow
->PixelToLogic(aPnt
);
283 SdrHdl
* pHdl
= mpView
->PickHandle(aPnt
);
287 mbLeftButtonDown
= false;
291 ::sdr::table::SdrTableObj
* pTableObj
= dynamic_cast< ::sdr::table::SdrTableObj
* >( mxTableObj
.get() );
293 if( !pWindow
|| !pTableObj
|| eHit
== SDRTABLEHIT_NONE
)
295 mbLeftButtonDown
= false;
305 bool SvxTableController::onMouseButtonUp(const MouseEvent
& rMEvt
, Window
* /*pWin*/)
307 if( !checkTableObject() )
310 mbLeftButtonDown
= false;
312 if( rMEvt
.GetClicks() == 2 )
320 bool SvxTableController::onMouseMove(const MouseEvent
& rMEvt
, Window
* pWindow
)
322 if( !checkTableObject() )
331 SdrTableObj
* pTableObj
= dynamic_cast< SdrTableObj
* >( mxTableObj
.get() );
333 if( mbLeftButtonDown
&& pTableObj
&& pTableObj
->CheckTableHit( pWindow
->PixelToLogic(rMEvt
.GetPosPixel()), aPos
.mnCol
, aPos
.mnRow
, 0 ) != SDRTABLEHIT_NONE
)
335 if(aPos
!= maMouseDownPos
)
337 if( mbCellSelectionMode
)
339 setSelectedCells( maMouseDownPos
, aPos
);
344 StartSelection( maMouseDownPos
);
347 else if( mbCellSelectionMode
)
349 UpdateSelection( aPos
);
358 void SvxTableController::onSelectionHasChanged()
360 bool bSelected
= false;
362 SdrTableObj
* pTableObj
= dynamic_cast< SdrTableObj
* >( mxTableObj
.get() );
363 if( pTableObj
&& pTableObj
->IsTextEditActive() )
365 pTableObj
->getActiveCellPos( maCursorFirstPos
);
366 maCursorLastPos
= maCursorFirstPos
;
367 mbCellSelectionMode
= false;
371 const SdrMarkList
& rMarkList
= mpView
->GetMarkedObjectList();
372 if( rMarkList
.GetMarkCount() == 1 )
373 bSelected
= mxTableObj
.get() == rMarkList
.GetMark(0)->GetMarkedSdrObj();
374 /* fdo#46186 Selecting the table means selecting the entire cells */
375 if (!hasSelectedCells() && pTableObj
)
377 maCursorFirstPos
= pTableObj
->getFirstCell();
378 maCursorLastPos
= pTableObj
->getLastCell();
379 mbCellSelectionMode
=true;
385 updateSelectionOverlay();
389 destroySelectionOverlay();
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 sal_uInt16 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();
495 void SvxTableController::onInsert( sal_uInt16 nSId
, const SfxItemSet
* pArgs
)
497 ::sdr::table::SdrTableObj
* pTableObj
= dynamic_cast< ::sdr::table::SdrTableObj
* >( mxTableObj
.get() );
501 if( mxTable
.is() ) try
504 bool bInsertAfter
= true;
505 sal_uInt16 nCount
= 0;
508 const SfxPoolItem
* pItem
= 0;
509 pArgs
->GetItemState(nSId
, false, &pItem
);
512 nCount
= ((const SfxInt16Item
* )pItem
)->GetValue();
513 if(SFX_ITEM_SET
== pArgs
->GetItemState(SID_TABLE_PARAM_INSERT_AFTER
, true, &pItem
))
514 bInsertAfter
= ((const SfxBoolItem
* )pItem
)->GetValue();
518 CellPos aStart
, aEnd
;
519 if( hasSelectedCells() )
521 getSelectedCells( aStart
, aEnd
);
527 aStart
.mnCol
= mxTable
->getColumnCount() - 1;
528 aStart
.mnRow
= mxTable
->getRowCount() - 1;
533 if( pTableObj
->IsTextEditActive() )
534 mpView
->SdrEndTextEdit(true);
538 const OUString
sSize( "Size" );
540 const bool bUndo
= mpModel
&& mpModel
->IsUndoEnabled();
544 case SID_TABLE_INSERT_COL
:
546 TableModelNotifyGuard
aGuard( mxTable
.get() );
550 mpModel
->BegUndo( ImpGetResStr(STR_TABLE_INSCOL
) );
551 mpModel
->AddUndo( mpModel
->GetSdrUndoFactory().CreateUndoGeoObject(*pTableObj
) );
554 Reference
< XTableColumns
> xCols( mxTable
->getColumns() );
555 const sal_Int32 nNewColumns
= (nCount
== 0) ? (aEnd
.mnCol
- aStart
.mnCol
+ 1) : nCount
;
556 const sal_Int32 nNewStartColumn
= aEnd
.mnCol
+ (bInsertAfter
? 1 : 0);
557 xCols
->insertByIndex( nNewStartColumn
, nNewColumns
);
559 for( sal_Int32 nOffset
= 0; nOffset
< nNewColumns
; nOffset
++ )
561 // Resolves fdo#61540
562 // On Insert before, the reference column whose size is going to be
563 // used for newly created column(s) is wrong. As the new columns are
564 // inserted before the reference column, the reference column moved
565 // to the new position by no., of new columns i.e (earlier+newcolumns).
566 Reference
< XPropertySet
>(xCols
->getByIndex(nNewStartColumn
+nOffset
), UNO_QUERY_THROW
)->
567 setPropertyValue( sSize
,
568 Reference
< XPropertySet
>(xCols
->getByIndex( bInsertAfter
?nNewStartColumn
-1:nNewStartColumn
+nNewColumns
), UNO_QUERY_THROW
)->
569 getPropertyValue( sSize
) );
575 aStart
.mnCol
= nNewStartColumn
;
577 aEnd
.mnCol
= aStart
.mnCol
+ nNewColumns
- 1;
578 aEnd
.mnRow
= mxTable
->getRowCount() - 1;
582 case SID_TABLE_INSERT_ROW
:
584 TableModelNotifyGuard
aGuard( mxTable
.get() );
588 mpModel
->BegUndo( ImpGetResStr(STR_TABLE_INSROW
) );
589 mpModel
->AddUndo( mpModel
->GetSdrUndoFactory().CreateUndoGeoObject(*pTableObj
) );
592 Reference
< XTableRows
> xRows( mxTable
->getRows() );
593 const sal_Int32 nNewRows
= (nCount
== 0) ? (aEnd
.mnRow
- aStart
.mnRow
+ 1) : nCount
;
594 const sal_Int32 nNewRowStart
= aEnd
.mnRow
+ (bInsertAfter
? 1 : 0);
595 xRows
->insertByIndex( nNewRowStart
, nNewRows
);
597 for( sal_Int32 nOffset
= 0; nOffset
< nNewRows
; nOffset
++ )
599 Reference
< XPropertySet
>( xRows
->getByIndex( aEnd
.mnRow
+ nOffset
+ 1 ), UNO_QUERY_THROW
)->
600 setPropertyValue( sSize
,
601 Reference
< XPropertySet
>( xRows
->getByIndex( aStart
.mnRow
+ nOffset
), UNO_QUERY_THROW
)->
602 getPropertyValue( sSize
) );
609 aStart
.mnRow
= nNewRowStart
;
610 aEnd
.mnCol
= mxTable
->getColumnCount() - 1;
611 aEnd
.mnRow
= aStart
.mnRow
+ nNewRows
- 1;
616 StartSelection( aStart
);
617 UpdateSelection( aEnd
);
621 OSL_FAIL("svx::SvxTableController::onInsert(), exception caught!");
627 void SvxTableController::onDelete( sal_uInt16 nSId
)
629 ::sdr::table::SdrTableObj
* pTableObj
= dynamic_cast< ::sdr::table::SdrTableObj
* >( mxTableObj
.get() );
633 if( mxTable
.is() && hasSelectedCells() )
635 CellPos aStart
, aEnd
;
636 getSelectedCells( aStart
, aEnd
);
638 if( pTableObj
->IsTextEditActive() )
639 mpView
->SdrEndTextEdit(true);
643 bool bDeleteTable
= false;
646 case SID_TABLE_DELETE_COL
:
648 const sal_Int32 nRemovedColumns
= aEnd
.mnCol
- aStart
.mnCol
+ 1;
649 if( nRemovedColumns
== mxTable
->getColumnCount() )
655 Reference
< XTableColumns
> xCols( mxTable
->getColumns() );
656 xCols
->removeByIndex( aStart
.mnCol
, nRemovedColumns
);
661 case SID_TABLE_DELETE_ROW
:
663 const sal_Int32 nRemovedRows
= aEnd
.mnRow
- aStart
.mnRow
+ 1;
664 if( nRemovedRows
== mxTable
->getRowCount() )
670 Reference
< XTableRows
> xRows( mxTable
->getRows() );
671 xRows
->removeByIndex( aStart
.mnRow
, nRemovedRows
);
678 mpView
->DeleteMarkedObj();
686 void SvxTableController::onSelect( sal_uInt16 nSId
)
690 const sal_Int32 nRowCount
= mxTable
->getRowCount();
691 const sal_Int32 nColCount
= mxTable
->getColumnCount();
692 if( nRowCount
&& nColCount
)
694 CellPos aStart
, aEnd
;
695 getSelectedCells( aStart
, aEnd
);
699 case SID_TABLE_SELECT_ALL
:
700 aEnd
.mnCol
= 0; aEnd
.mnRow
= 0;
701 aStart
.mnCol
= nColCount
- 1; aStart
.mnRow
= nRowCount
- 1;
703 case SID_TABLE_SELECT_COL
:
704 aEnd
.mnRow
= nRowCount
- 1;
707 case SID_TABLE_SELECT_ROW
:
708 aEnd
.mnCol
= nColCount
- 1;
713 StartSelection( aEnd
);
714 gotoCell( aStart
, true, 0 );
720 void SvxTableController::onFormatTable( SfxRequest
& rReq
)
722 ::sdr::table::SdrTableObj
* pTableObj
= dynamic_cast< ::sdr::table::SdrTableObj
* >( mxTableObj
.get() );
726 const SfxItemSet
* pArgs
= rReq
.GetArgs();
728 if( !pArgs
&& pTableObj
->GetModel() )
730 SfxItemSet
aNewAttr( pTableObj
->GetModel()->GetItemPool() );
732 // merge drawing layer text distance items into SvxBoxItem used by the dialog
733 SvxBoxItem
aBoxItem( static_cast< const SvxBoxItem
& >( aNewAttr
.Get( SDRATTR_TABLE_BORDER
) ) );
734 aBoxItem
.SetDistance( sal::static_int_cast
< sal_uInt16
>( ((SdrTextLeftDistItem
&)(aNewAttr
.Get(SDRATTR_TEXT_LEFTDIST
))).GetValue()), BOX_LINE_LEFT
);
735 aBoxItem
.SetDistance( sal::static_int_cast
< sal_uInt16
>( ((SdrTextRightDistItem
&)(aNewAttr
.Get(SDRATTR_TEXT_RIGHTDIST
))).GetValue()), BOX_LINE_RIGHT
);
736 aBoxItem
.SetDistance( sal::static_int_cast
< sal_uInt16
>( ((SdrTextUpperDistItem
&)(aNewAttr
.Get(SDRATTR_TEXT_UPPERDIST
))).GetValue()), BOX_LINE_TOP
);
737 aBoxItem
.SetDistance( sal::static_int_cast
< sal_uInt16
>( ((SdrTextLowerDistItem
&)(aNewAttr
.Get(SDRATTR_TEXT_LOWERDIST
))).GetValue()), BOX_LINE_BOTTOM
);
739 SvxBoxInfoItem
aBoxInfoItem( static_cast< const SvxBoxInfoItem
& >( aNewAttr
.Get( SDRATTR_TABLE_BORDER_INNER
) ) );
741 MergeAttrFromSelectedCells(aNewAttr
, false);
742 FillCommonBorderAttrFromSelectedCells( aBoxItem
, aBoxInfoItem
);
743 aNewAttr
.Put( aBoxItem
);
744 aNewAttr
.Put( aBoxInfoItem
);
746 SvxAbstractDialogFactory
* pFact
= SvxAbstractDialogFactory::Create();
747 boost::scoped_ptr
< SfxAbstractTabDialog
> pDlg( pFact
? pFact
->CreateSvxFormatCellsDialog( NULL
, &aNewAttr
, pTableObj
->GetModel(), pTableObj
) : 0 );
748 // Even Cancel Button is returning positive(101) value,
749 if( pDlg
.get() && ( pDlg
->Execute() == RET_OK
) )
751 SfxItemSet
aNewSet( aNewAttr
);
752 aNewSet
.Put( *(pDlg
->GetOutputItemSet ()) );
754 SvxBoxItem
aNewBoxItem( static_cast< const SvxBoxItem
& >( aNewSet
.Get( SDRATTR_TABLE_BORDER
) ) );
756 if( aNewBoxItem
.GetDistance( BOX_LINE_LEFT
) != aBoxItem
.GetDistance( BOX_LINE_LEFT
) )
757 aNewSet
.Put(SdrTextLeftDistItem( aNewBoxItem
.GetDistance( BOX_LINE_LEFT
) ) );
759 if( aNewBoxItem
.GetDistance( BOX_LINE_RIGHT
) != aBoxItem
.GetDistance( BOX_LINE_RIGHT
) )
760 aNewSet
.Put(SdrTextRightDistItem( aNewBoxItem
.GetDistance( BOX_LINE_RIGHT
) ) );
762 if( aNewBoxItem
.GetDistance( BOX_LINE_TOP
) != aBoxItem
.GetDistance( BOX_LINE_TOP
) )
763 aNewSet
.Put(SdrTextUpperDistItem( aNewBoxItem
.GetDistance( BOX_LINE_TOP
) ) );
765 if( aNewBoxItem
.GetDistance( BOX_LINE_BOTTOM
) != aBoxItem
.GetDistance( BOX_LINE_BOTTOM
) )
766 aNewSet
.Put(SdrTextLowerDistItem( aNewBoxItem
.GetDistance( BOX_LINE_BOTTOM
) ) );
768 SetAttrToSelectedCells(aNewSet
, false);
775 void SvxTableController::Execute( SfxRequest
& rReq
)
777 const sal_uInt16 nSId
= rReq
.GetSlot();
780 case SID_TABLE_INSERT_ROW
:
781 case SID_TABLE_INSERT_COL
:
782 onInsert( nSId
, rReq
.GetArgs() );
784 case SID_TABLE_DELETE_ROW
:
785 case SID_TABLE_DELETE_COL
:
788 case SID_TABLE_SELECT_ALL
:
789 case SID_TABLE_SELECT_COL
:
790 case SID_TABLE_SELECT_ROW
:
793 case SID_FORMAT_TABLE_DLG
:
794 onFormatTable( rReq
);
797 case SID_FRAME_LINESTYLE
:
798 case SID_FRAME_LINECOLOR
:
799 case SID_ATTR_BORDER
:
801 const SfxItemSet
* pArgs
= rReq
.GetArgs();
803 ApplyBorderAttr( *pArgs
);
807 case SID_ATTR_FILL_STYLE
:
809 const SfxItemSet
* pArgs
= rReq
.GetArgs();
811 SetAttributes( *pArgs
, false );
815 case SID_TABLE_MERGE_CELLS
:
819 case SID_TABLE_SPLIT_CELLS
:
823 case SID_TABLE_DISTRIBUTE_COLUMNS
:
827 case SID_TABLE_DISTRIBUTE_ROWS
:
831 case SID_TABLE_VERT_BOTTOM
:
832 case SID_TABLE_VERT_CENTER
:
833 case SID_TABLE_VERT_NONE
:
838 case SID_TABLE_SORT_DIALOG
:
839 case SID_TABLE_AUTOSUM
:
843 case SID_TABLE_STYLE
:
844 SetTableStyle( rReq
.GetArgs() );
847 case SID_TABLE_STYLE_SETTINGS
:
848 SetTableStyleSettings( rReq
.GetArgs() );
853 void SvxTableController::SetTableStyle( const SfxItemSet
* pArgs
)
855 SdrTableObj
* pTableObj
= dynamic_cast< ::sdr::table::SdrTableObj
* >( mxTableObj
.get() );
856 SdrModel
* pModel
= pTableObj
? pTableObj
->GetModel() : 0;
858 if( !pTableObj
|| !pModel
|| !pArgs
|| (SFX_ITEM_SET
!= pArgs
->GetItemState(SID_TABLE_STYLE
, false)) )
861 const SfxStringItem
* pArg
= dynamic_cast< const SfxStringItem
* >( &pArgs
->Get( SID_TABLE_STYLE
) );
862 if( pArg
&& mxTable
.is() ) try
864 Reference
< XStyleFamiliesSupplier
> xSFS( pModel
->getUnoModel(), UNO_QUERY_THROW
);
865 Reference
< XNameAccess
> xFamilyNameAccess( xSFS
->getStyleFamilies(), UNO_QUERY_THROW
);
866 const OUString
sFamilyName( "table" );
867 Reference
< XNameAccess
> xTableFamilyAccess( xFamilyNameAccess
->getByName( sFamilyName
), UNO_QUERY_THROW
);
869 if( xTableFamilyAccess
->hasByName( pArg
->GetValue() ) )
871 // found table style with the same name
872 Reference
< XIndexAccess
> xNewTableStyle( xTableFamilyAccess
->getByName( pArg
->GetValue() ), UNO_QUERY_THROW
);
874 const bool bUndo
= pModel
->IsUndoEnabled();
878 pModel
->BegUndo( ImpGetResStr(STR_TABLE_STYLE
) );
879 pModel
->AddUndo( new TableStyleUndo( *pTableObj
) );
882 pTableObj
->setTableStyle( xNewTableStyle
);
884 const sal_Int32 nRowCount
= mxTable
->getRowCount();
885 const sal_Int32 nColCount
= mxTable
->getColumnCount();
886 for( sal_Int32 nRow
= 0; nRow
< nRowCount
; nRow
++ )
888 for( sal_Int32 nCol
= 0; nCol
< nColCount
; nCol
++ ) try
890 CellRef
xCell( dynamic_cast< Cell
* >( mxTable
->getCellByPosition( nCol
, nRow
).get() ) );
893 SfxItemSet
aSet( xCell
->GetItemSet() );
894 bool bChanges
= false;
895 const SfxItemSet
& rStyleAttribs
= xCell
->GetStyleSheet()->GetItemSet();
897 for ( sal_uInt16 nWhich
= SDRATTR_START
; nWhich
<= SDRATTR_TABLE_LAST
; nWhich
++ )
899 if( (rStyleAttribs
.GetItemState( nWhich
) == SFX_ITEM_ON
) && (aSet
.GetItemState( nWhich
) == SFX_ITEM_ON
) )
901 aSet
.ClearItem( nWhich
);
911 xCell
->SetMergedItemSetAndBroadcast( aSet
, true );
917 OSL_FAIL( "svx::SvxTableController::SetTableStyle(), exception caught!" );
927 OSL_FAIL( "svx::SvxTableController::SetTableStyle(), exception caught!" );
931 void SvxTableController::SetTableStyleSettings( const SfxItemSet
* pArgs
)
933 SdrTableObj
* pTableObj
= dynamic_cast< ::sdr::table::SdrTableObj
* >( mxTableObj
.get() );
934 SdrModel
* pModel
= pTableObj
? pTableObj
->GetModel() : 0;
936 if( !pTableObj
|| !pModel
)
939 TableStyleSettings
aSettings( pTableObj
->getTableStyleSettings() );
941 const SfxPoolItem
*pPoolItem
=NULL
;
943 if( (SFX_ITEM_SET
== pArgs
->GetItemState(ID_VAL_USEFIRSTROWSTYLE
, false,&pPoolItem
)) )
944 aSettings
.mbUseFirstRow
= static_cast< const SfxBoolItem
* >(pPoolItem
)->GetValue();
946 if( (SFX_ITEM_SET
== pArgs
->GetItemState(ID_VAL_USELASTROWSTYLE
, false,&pPoolItem
)) )
947 aSettings
.mbUseLastRow
= static_cast< const SfxBoolItem
* >(pPoolItem
)->GetValue();
949 if( (SFX_ITEM_SET
== pArgs
->GetItemState(ID_VAL_USEBANDINGROWSTYLE
, false,&pPoolItem
)) )
950 aSettings
.mbUseRowBanding
= static_cast< const SfxBoolItem
* >(pPoolItem
)->GetValue();
952 if( (SFX_ITEM_SET
== pArgs
->GetItemState(ID_VAL_USEFIRSTCOLUMNSTYLE
, false,&pPoolItem
)) )
953 aSettings
.mbUseFirstColumn
= static_cast< const SfxBoolItem
* >(pPoolItem
)->GetValue();
955 if( (SFX_ITEM_SET
== pArgs
->GetItemState(ID_VAL_USELASTCOLUMNSTYLE
, false,&pPoolItem
)) )
956 aSettings
.mbUseLastColumn
= static_cast< const SfxBoolItem
* >(pPoolItem
)->GetValue();
958 if( (SFX_ITEM_SET
== pArgs
->GetItemState(ID_VAL_USEBANDINGCOLUMNSTYLE
, false,&pPoolItem
)) )
959 aSettings
.mbUseColumnBanding
= static_cast< const SfxBoolItem
* >(pPoolItem
)->GetValue();
961 if( aSettings
== pTableObj
->getTableStyleSettings() )
964 const bool bUndo
= pModel
->IsUndoEnabled();
968 pModel
->BegUndo( ImpGetResStr(STR_TABLE_STYLE_SETTINGS
) );
969 pModel
->AddUndo( new TableStyleUndo( *pTableObj
) );
972 pTableObj
->setTableStyleSettings( aSettings
);
978 void SvxTableController::SetVertical( sal_uInt16 nSId
)
980 SdrTableObj
* pTableObj
= dynamic_cast< ::sdr::table::SdrTableObj
* >( mxTableObj
.get() );
981 if( mxTable
.is() && pTableObj
)
983 TableModelNotifyGuard
aGuard( mxTable
.get() );
985 CellPos aStart
, aEnd
;
986 getSelectedCells( aStart
, aEnd
);
988 SdrTextVertAdjust eAdj
= SDRTEXTVERTADJUST_TOP
;
992 case SID_TABLE_VERT_BOTTOM
:
993 eAdj
= SDRTEXTVERTADJUST_BOTTOM
;
995 case SID_TABLE_VERT_CENTER
:
996 eAdj
= SDRTEXTVERTADJUST_CENTER
;
998 //case SID_TABLE_VERT_NONE:
1003 SdrTextVertAdjustItem
aItem( eAdj
);
1005 for( sal_Int32 nRow
= aStart
.mnRow
; nRow
<= aEnd
.mnRow
; nRow
++ )
1007 for( sal_Int32 nCol
= aStart
.mnCol
; nCol
<= aEnd
.mnCol
; nCol
++ )
1009 CellRef
xCell( dynamic_cast< Cell
* >( mxTable
->getCellByPosition( nCol
, nRow
).get() ) );
1011 xCell
->SetMergedItem(aItem
);
1019 void SvxTableController::MergeMarkedCells()
1021 CellPos aStart
, aEnd
;
1022 getSelectedCells( aStart
, aEnd
);
1023 SdrTableObj
* pTableObj
= dynamic_cast< ::sdr::table::SdrTableObj
* >( mxTableObj
.get() );
1026 if( pTableObj
->IsTextEditActive() )
1027 mpView
->SdrEndTextEdit(true);
1029 TableModelNotifyGuard
aGuard( mxTable
.get() );
1030 MergeRange( aStart
.mnCol
, aStart
.mnRow
, aEnd
.mnCol
, aEnd
.mnRow
);
1034 void SvxTableController::SplitMarkedCells()
1038 CellPos aStart
, aEnd
;
1039 getSelectedCells( aStart
, aEnd
);
1041 SvxAbstractDialogFactory
* pFact
= SvxAbstractDialogFactory::Create();
1042 boost::scoped_ptr
< SvxAbstractSplittTableDialog
> xDlg( pFact
? pFact
->CreateSvxSplittTableDialog( NULL
, false, 99, 99 ) : 0 );
1043 if( xDlg
.get() && xDlg
->Execute() )
1045 const sal_Int32 nCount
= xDlg
->GetCount() - 1;
1049 getSelectedCells( aStart
, aEnd
);
1051 Reference
< XMergeableCellRange
> xRange( mxTable
->createCursorByRange( mxTable
->getCellRangeByPosition( aStart
.mnCol
, aStart
.mnRow
, aEnd
.mnCol
, aEnd
.mnRow
) ), UNO_QUERY_THROW
);
1053 const sal_Int32 nRowCount
= mxTable
->getRowCount();
1054 const sal_Int32 nColCount
= mxTable
->getColumnCount();
1057 SdrTableObj
* pTableObj
= dynamic_cast< SdrTableObj
* >( mxTableObj
.get() );
1060 if( pTableObj
->IsTextEditActive() )
1061 mpView
->SdrEndTextEdit(true);
1063 TableModelNotifyGuard
aGuard( mxTable
.get() );
1065 const bool bUndo
= mpModel
&& mpModel
->IsUndoEnabled();
1068 mpModel
->BegUndo( ImpGetResStr(STR_TABLE_SPLIT
) );
1069 mpModel
->AddUndo( mpModel
->GetSdrUndoFactory().CreateUndoGeoObject(*pTableObj
) );
1072 if( xDlg
->IsHorizontal() )
1074 xRange
->split( 0, nCount
);
1078 xRange
->split( nCount
, 0 );
1084 aEnd
.mnRow
+= mxTable
->getRowCount() - nRowCount
;
1085 aEnd
.mnCol
+= mxTable
->getColumnCount() - nColCount
;
1087 setSelectedCells( aStart
, aEnd
);
1092 void SvxTableController::DistributeColumns()
1094 SdrTableObj
* pTableObj
= dynamic_cast< SdrTableObj
* >( mxTableObj
.get() );
1097 const bool bUndo
= mpModel
&& mpModel
->IsUndoEnabled();
1100 mpModel
->BegUndo( ImpGetResStr(STR_TABLE_DISTRIBUTE_COLUMNS
) );
1101 mpModel
->AddUndo( mpModel
->GetSdrUndoFactory().CreateUndoGeoObject(*pTableObj
) );
1104 CellPos aStart
, aEnd
;
1105 getSelectedCells( aStart
, aEnd
);
1106 pTableObj
->DistributeColumns( aStart
.mnCol
, aEnd
.mnCol
);
1113 void SvxTableController::DistributeRows()
1115 SdrTableObj
* pTableObj
= dynamic_cast< SdrTableObj
* >( mxTableObj
.get() );
1118 const bool bUndo
= mpModel
&& mpModel
->IsUndoEnabled();
1121 mpModel
->BegUndo( ImpGetResStr(STR_TABLE_DISTRIBUTE_ROWS
) );
1122 mpModel
->AddUndo( mpModel
->GetSdrUndoFactory().CreateUndoGeoObject(*pTableObj
) );
1125 CellPos aStart
, aEnd
;
1126 getSelectedCells( aStart
, aEnd
);
1127 pTableObj
->DistributeRows( aStart
.mnRow
, aEnd
.mnRow
);
1134 bool SvxTableController::DeleteMarked()
1136 if( mbCellSelectionMode
)
1140 CellPos aStart
, aEnd
;
1141 getSelectedCells( aStart
, aEnd
);
1142 for( sal_Int32 nRow
= aStart
.mnRow
; nRow
<= aEnd
.mnRow
; nRow
++ )
1144 for( sal_Int32 nCol
= aStart
.mnCol
; nCol
<= aEnd
.mnCol
; nCol
++ )
1146 CellRef
xCell( dynamic_cast< Cell
* >( mxTable
->getCellByPosition( nCol
, nRow
).get() ) );
1148 xCell
->SetOutlinerParaObject( 0 );
1160 bool SvxTableController::GetStyleSheet( SfxStyleSheet
*& rpStyleSheet
) const
1162 if( hasSelectedCells() )
1168 SfxStyleSheet
* pRet
=0;
1171 CellPos aStart
, aEnd
;
1172 const_cast<SvxTableController
&>(*this).getSelectedCells( aStart
, aEnd
);
1174 for( sal_Int32 nRow
= aStart
.mnRow
; nRow
<= aEnd
.mnRow
; nRow
++ )
1176 for( sal_Int32 nCol
= aStart
.mnCol
; nCol
<= aEnd
.mnCol
; nCol
++ )
1178 CellRef
xCell( dynamic_cast< Cell
* >( mxTable
->getCellByPosition( nCol
, nRow
).get() ) );
1181 SfxStyleSheet
* pSS
=xCell
->GetStyleSheet();
1186 else if(pRet
!= pSS
)
1194 rpStyleSheet
= pRet
;
1201 bool SvxTableController::SetStyleSheet( SfxStyleSheet
* pStyleSheet
, bool bDontRemoveHardAttr
)
1203 if( hasSelectedCells() && (!pStyleSheet
|| pStyleSheet
->GetFamily() == SFX_STYLE_FAMILY_FRAME
) )
1207 CellPos aStart
, aEnd
;
1208 getSelectedCells( aStart
, aEnd
);
1210 for( sal_Int32 nRow
= aStart
.mnRow
; nRow
<= aEnd
.mnRow
; nRow
++ )
1212 for( sal_Int32 nCol
= aStart
.mnCol
; nCol
<= aEnd
.mnCol
; nCol
++ )
1214 CellRef
xCell( dynamic_cast< Cell
* >( mxTable
->getCellByPosition( nCol
, nRow
).get() ) );
1216 xCell
->SetStyleSheet(pStyleSheet
,bDontRemoveHardAttr
);
1231 bool SvxTableController::checkTableObject()
1233 return mxTableObj
.is();
1238 sal_uInt16
SvxTableController::getKeyboardAction( const KeyEvent
& rKEvt
, Window
* /*pWindow*/ )
1240 const bool bMod1
= rKEvt
.GetKeyCode().IsMod1(); // ctrl
1241 const bool bMod2
= rKEvt
.GetKeyCode().IsMod2(); // Alt
1243 const bool bTextEdit
= mpView
->IsTextEdit();
1245 sal_uInt16 nAction
= ACTION_HANDLED_BY_VIEW
;
1247 ::sdr::table::SdrTableObj
* pTableObj
= dynamic_cast< ::sdr::table::SdrTableObj
* >( mxTableObj
.get() );
1251 // handle special keys
1252 const sal_Int16 nCode
= rKEvt
.GetKeyCode().GetCode();
1255 case awt::Key::ESCAPE
: // handle escape
1259 // escape during text edit ends text edit
1260 nAction
= ACTION_STOP_TEXT_EDIT
;
1262 if( mbCellSelectionMode
)
1264 // escape with selected cells removes selection
1265 nAction
= ACTION_REMOVE_SELECTION
;
1269 case awt::Key::RETURN
: // handle return
1271 if( !bMod1
&& !bMod2
&& !bTextEdit
)
1273 // when not already editing, return starts text edit
1274 setSelectionStart( pTableObj
->getFirstCell() );
1275 nAction
= ACTION_EDIT_CELL
;
1279 case awt::Key::F2
: // f2 toggles text edit
1281 if( bMod1
|| bMod2
) // f2 with modifiers is handled by the view
1284 else if( bTextEdit
)
1286 // f2 during text edit stops text edit
1287 nAction
= ACTION_STOP_TEXT_EDIT
;
1289 else if( mbCellSelectionMode
)
1291 // f2 with selected cells removes selection
1292 nAction
= ACTION_REMOVE_SELECTION
;
1296 // f2 with no selection and no text edit starts text edit
1297 setSelectionStart( pTableObj
->getFirstCell() );
1298 nAction
= ACTION_EDIT_CELL
;
1302 case awt::Key::HOME
:
1303 case awt::Key::NUM7
:
1305 if( (bMod1
|| bMod2
) && (bTextEdit
|| mbCellSelectionMode
) )
1307 if( bMod1
&& !bMod2
)
1309 // ctrl + home jumps to first cell
1310 nAction
= ACTION_GOTO_FIRST_CELL
;
1312 else if( !bMod1
&& bMod2
)
1314 // alt + home jumps to first column
1315 nAction
= ACTION_GOTO_FIRST_COLUMN
;
1321 case awt::Key::NUM1
:
1323 if( (bMod1
|| bMod2
) && (bTextEdit
|| mbCellSelectionMode
) )
1325 if( bMod1
&& !bMod2
)
1327 // ctrl + end jumps to last cell
1328 nAction
= ACTION_GOTO_LAST_CELL
;
1330 else if( !bMod1
&& bMod2
)
1332 // alt + home jumps to last column
1333 nAction
= ACTION_GOTO_LAST_COLUMN
;
1341 if( bTextEdit
|| mbCellSelectionMode
)
1342 nAction
= ACTION_TAB
;
1347 case awt::Key::NUM8
:
1348 case awt::Key::DOWN
:
1349 case awt::Key::NUM2
:
1350 case awt::Key::LEFT
:
1351 case awt::Key::NUM4
:
1352 case awt::Key::RIGHT
:
1353 case awt::Key::NUM6
:
1355 bool bTextMove
= false;
1357 if( !bMod1
&& bMod2
)
1359 if( (nCode
== awt::Key::UP
) || (nCode
== awt::Key::NUM8
) )
1361 nAction
= ACTION_GOTO_LEFT_CELL
;
1363 else if( (nCode
== awt::Key::DOWN
) || (nCode
== awt::Key::NUM2
) )
1365 nAction
= ACTION_GOTO_RIGHT_CELL
;
1372 OutlinerView
* pOLV
= mpView
->GetTextEditOutlinerView();
1376 // during text edit, check if we navigate out of the cell
1377 ESelection aOldSelection
= pOLV
->GetSelection();
1378 pOLV
->PostKeyEvent(rKEvt
);
1379 bTextMove
= pOLV
&& ( aOldSelection
.IsEqual(pOLV
->GetSelection()) );
1382 nAction
= ACTION_NONE
;
1387 if( mbCellSelectionMode
|| bTextMove
)
1389 // no text edit, navigate in cells if selection active
1392 case awt::Key::LEFT
:
1393 case awt::Key::NUM4
:
1394 nAction
= ACTION_GOTO_LEFT_CELL
;
1396 case awt::Key::RIGHT
:
1397 case awt::Key::NUM6
:
1398 nAction
= ACTION_GOTO_RIGHT_CELL
;
1400 case awt::Key::DOWN
:
1401 case awt::Key::NUM2
:
1402 nAction
= ACTION_GOTO_DOWN_CELL
;
1405 case awt::Key::NUM8
:
1406 nAction
= ACTION_GOTO_UP_CELL
;
1412 case awt::Key::PAGEUP
:
1414 nAction
= ACTION_GOTO_FIRST_ROW
;
1417 case awt::Key::PAGEDOWN
:
1419 nAction
= ACTION_GOTO_LAST_ROW
;
1425 bool SvxTableController::executeAction( sal_uInt16 nAction
, bool bSelect
, Window
* pWindow
)
1427 ::sdr::table::SdrTableObj
* pTableObj
= dynamic_cast< ::sdr::table::SdrTableObj
* >( mxTableObj
.get() );
1433 case ACTION_GOTO_FIRST_CELL
:
1435 gotoCell( pTableObj
->getFirstCell(), bSelect
, pWindow
, nAction
);
1439 case ACTION_GOTO_LEFT_CELL
:
1441 gotoCell( pTableObj
->getLeftCell( getSelectionEnd(), !bSelect
), bSelect
, pWindow
, nAction
);
1445 case ACTION_GOTO_RIGHT_CELL
:
1447 gotoCell( pTableObj
->getRightCell( getSelectionEnd(), !bSelect
), bSelect
, pWindow
, nAction
);
1451 case ACTION_GOTO_LAST_CELL
:
1453 gotoCell( pTableObj
->getLastCell(), bSelect
, pWindow
, nAction
);
1457 case ACTION_GOTO_FIRST_COLUMN
:
1459 CellPos
aPos( pTableObj
->getFirstCell().mnCol
, getSelectionEnd().mnRow
);
1460 gotoCell( aPos
, bSelect
, pWindow
, nAction
);
1464 case ACTION_GOTO_LAST_COLUMN
:
1466 CellPos
aPos( pTableObj
->getLastCell().mnCol
, getSelectionEnd().mnRow
);
1467 gotoCell( aPos
, bSelect
, pWindow
, nAction
);
1471 case ACTION_GOTO_FIRST_ROW
:
1473 CellPos
aPos( getSelectionEnd().mnCol
, pTableObj
->getFirstCell().mnRow
);
1474 gotoCell( aPos
, bSelect
, pWindow
, nAction
);
1478 case ACTION_GOTO_UP_CELL
:
1480 gotoCell( pTableObj
->getUpCell(getSelectionEnd(), !bSelect
), bSelect
, pWindow
, nAction
);
1484 case ACTION_GOTO_DOWN_CELL
:
1486 gotoCell( pTableObj
->getDownCell(getSelectionEnd(), !bSelect
), bSelect
, pWindow
, nAction
);
1490 case ACTION_GOTO_LAST_ROW
:
1492 CellPos
aPos( getSelectionEnd().mnCol
, pTableObj
->getLastCell().mnRow
);
1493 gotoCell( aPos
, bSelect
, pWindow
, nAction
);
1497 case ACTION_EDIT_CELL
:
1498 EditCell( getSelectionStart(), pWindow
, 0, nAction
);
1501 case ACTION_STOP_TEXT_EDIT
:
1505 case ACTION_REMOVE_SELECTION
:
1509 case ACTION_START_SELECTION
:
1510 StartSelection( getSelectionStart() );
1516 gotoCell( pTableObj
->getPreviousCell( getSelectionEnd(), true ), false, pWindow
, nAction
);
1519 CellPos
aSelectionEnd( getSelectionEnd() );
1520 CellPos
aNextCell( pTableObj
->getNextCell( aSelectionEnd
, true ) );
1521 if( aSelectionEnd
== aNextCell
)
1523 onInsert( SID_TABLE_INSERT_ROW
, 0 );
1524 aNextCell
= pTableObj
->getNextCell( aSelectionEnd
, true );
1526 gotoCell( aNextCell
, false, pWindow
, nAction
);
1532 return nAction
!= ACTION_HANDLED_BY_VIEW
;
1537 void SvxTableController::gotoCell( const CellPos
& rPos
, bool bSelect
, Window
* pWindow
, sal_uInt16 nAction
)
1539 if( mxTableObj
.is() && static_cast<SdrTableObj
*>(mxTableObj
.get())->IsTextEditActive() )
1540 mpView
->SdrEndTextEdit(true);
1544 maCursorLastPos
= rPos
;
1545 if( mxTableObj
.is() )
1546 static_cast< SdrTableObj
* >( mxTableObj
.get() )->setActiveCell( rPos
);
1548 if( !mbCellSelectionMode
)
1550 setSelectedCells( maCursorFirstPos
, rPos
);
1554 UpdateSelection( rPos
);
1560 EditCell( rPos
, pWindow
, 0, nAction
);
1566 const CellPos
& SvxTableController::getSelectionStart()
1568 checkCell( maCursorFirstPos
);
1569 return maCursorFirstPos
;
1574 void SvxTableController::setSelectionStart( const CellPos
& rPos
)
1576 maCursorFirstPos
= rPos
;
1581 const CellPos
& SvxTableController::getSelectionEnd()
1583 checkCell( maCursorLastPos
);
1584 return maCursorLastPos
;
1589 void SvxTableController::MergeRange( sal_Int32 nFirstCol
, sal_Int32 nFirstRow
, sal_Int32 nLastCol
, sal_Int32 nLastRow
)
1591 if( mxTable
.is() ) try
1593 Reference
< XMergeableCellRange
> xRange( mxTable
->createCursorByRange( mxTable
->getCellRangeByPosition( nFirstCol
, nFirstRow
,nLastCol
, nLastRow
) ), UNO_QUERY_THROW
);
1594 if( xRange
->isMergeable() )
1596 const bool bUndo
= mpModel
&& mpModel
->IsUndoEnabled();
1599 mpModel
->BegUndo( ImpGetResStr(STR_TABLE_MERGE
) );
1600 mpModel
->AddUndo( mpModel
->GetSdrUndoFactory().CreateUndoGeoObject(*mxTableObj
.get()) );
1611 DBG_ASSERT( false, "sdr::table::SvxTableController::MergeRange(), exception caught!" );
1619 void SvxTableController::checkCell( CellPos
& rPos
)
1621 if( mxTable
.is() ) try
1623 if( rPos
.mnCol
>= mxTable
->getColumnCount() )
1624 rPos
.mnCol
= mxTable
->getColumnCount()-1;
1626 if( rPos
.mnRow
>= mxTable
->getRowCount() )
1627 rPos
.mnRow
= mxTable
->getRowCount()-1;
1631 OSL_FAIL("sdr::table::SvxTableController::checkCell(), exception caught!" );
1637 void SvxTableController::findMergeOrigin( CellPos
& rPos
)
1639 if( mxTable
.is() ) try
1641 Reference
< XMergeableCell
> xCell( mxTable
->getCellByPosition( rPos
.mnCol
, rPos
.mnRow
), UNO_QUERY_THROW
);
1642 if( xCell
.is() && xCell
->isMerged() )
1644 ::findMergeOrigin( mxTable
, rPos
.mnCol
, rPos
.mnRow
, rPos
.mnCol
, rPos
.mnRow
);
1649 OSL_FAIL("sdr::table::SvxTableController::findMergeOrigin(), exception caught!" );
1655 void SvxTableController::EditCell( const CellPos
& rPos
, ::Window
* pWindow
, const awt::MouseEvent
* pMouseEvent
/*= 0*/, sal_uInt16 nAction
/*= ACTION_NONE */ )
1657 SdrPageView
* pPV
= mpView
->GetSdrPageView();
1659 ::sdr::table::SdrTableObj
* pTableObj
= dynamic_cast< ::sdr::table::SdrTableObj
* >( mxTableObj
.get() );
1660 if( pTableObj
&& pTableObj
->GetPage() == pPV
->GetPage() )
1662 bool bEmptyOutliner
= false;
1664 if(!pTableObj
->GetOutlinerParaObject() && mpView
->GetTextEditOutliner())
1666 ::Outliner
* pOutl
= mpView
->GetTextEditOutliner();
1667 sal_Int32 nParaAnz
= pOutl
->GetParagraphCount();
1668 Paragraph
* p1stPara
= pOutl
->GetParagraph( 0 );
1670 if(nParaAnz
==1 && p1stPara
)
1672 // Bei nur einem Pararaph
1673 if (pOutl
->GetText(p1stPara
).isEmpty())
1675 bEmptyOutliner
= true;
1680 CellPos
aPos( rPos
);
1681 findMergeOrigin( aPos
);
1683 if( pTableObj
!= mpView
->GetTextEditObject() || bEmptyOutliner
|| !pTableObj
->IsTextEditActive( aPos
) )
1685 if( pTableObj
->IsTextEditActive() )
1686 mpView
->SdrEndTextEdit(true);
1688 pTableObj
->setActiveCell( aPos
);
1690 // create new outliner, owner will be the SdrObjEditView
1691 SdrOutliner
* pOutl
= SdrMakeOutliner( OUTLINERMODE_OUTLINEOBJECT
, mpModel
);
1692 if( pTableObj
->IsVerticalWriting() )
1693 pOutl
->SetVertical( true );
1695 if(mpView
->SdrBeginTextEdit(pTableObj
, pPV
, pWindow
, true, pOutl
))
1697 maCursorLastPos
= maCursorFirstPos
= rPos
;
1699 OutlinerView
* pOLV
= mpView
->GetTextEditOutlinerView();
1705 ::MouseEvent
aMEvt( *pMouseEvent
);
1708 SdrHitKind eHit
= mpView
->PickAnything(aMEvt
, SDRMOUSEBUTTONDOWN
, aVEvt
);
1710 if (eHit
== SDRHIT_TEXTEDIT
)
1713 pOLV
->MouseButtonDown(aMEvt
);
1714 pOLV
->MouseMove(aMEvt
);
1715 pOLV
->MouseButtonUp(aMEvt
);
1716 // pOLV->MouseButtonDown(aMEvt);
1721 nAction
= ACTION_GOTO_LEFT_CELL
;
1727 // Move cursor to end of text
1728 ESelection aNewSelection
;
1730 const WritingMode eMode
= pTableObj
->GetWritingMode();
1731 if( ((nAction
== ACTION_GOTO_LEFT_CELL
) || (nAction
== ACTION_GOTO_RIGHT_CELL
)) && (eMode
!= WritingMode_TB_RL
) )
1733 const bool bLast
= ((nAction
== ACTION_GOTO_LEFT_CELL
) && (eMode
== WritingMode_LR_TB
)) ||
1734 ((nAction
== ACTION_GOTO_RIGHT_CELL
) && (eMode
== WritingMode_RL_TB
));
1737 aNewSelection
= ESelection(EE_PARA_NOT_FOUND
, EE_INDEX_NOT_FOUND
, EE_PARA_NOT_FOUND
, EE_INDEX_NOT_FOUND
);
1739 pOLV
->SetSelection(aNewSelection
);
1748 bool SvxTableController::StopTextEdit()
1750 if(mpView
->IsTextEdit())
1752 mpView
->SdrEndTextEdit();
1753 mpView
->SetCurrentObj(OBJ_TABLE
);
1754 mpView
->SetEditMode(SDREDITMODE_EDIT
);
1765 void SvxTableController::getSelectedCells( CellPos
& rFirst
, CellPos
& rLast
)
1767 if( mbCellSelectionMode
)
1769 checkCell( maCursorFirstPos
);
1770 checkCell( maCursorLastPos
);
1772 rFirst
.mnCol
= std::min( maCursorFirstPos
.mnCol
, maCursorLastPos
.mnCol
);
1773 rFirst
.mnRow
= std::min( maCursorFirstPos
.mnRow
, maCursorLastPos
.mnRow
);
1774 rLast
.mnCol
= std::max( maCursorFirstPos
.mnCol
, maCursorLastPos
.mnCol
);
1775 rLast
.mnRow
= std::max( maCursorFirstPos
.mnRow
, maCursorLastPos
.mnRow
);
1778 if( mxTable
.is() ) do
1781 for( sal_Int32 nRow
= rFirst
.mnRow
; nRow
<= rLast
.mnRow
&& !bExt
; nRow
++ )
1783 for( sal_Int32 nCol
= rFirst
.mnCol
; nCol
<= rLast
.mnCol
&& !bExt
; nCol
++ )
1785 Reference
< XMergeableCell
> xCell( mxTable
->getCellByPosition( nCol
, nRow
), UNO_QUERY
);
1789 if( xCell
->isMerged() )
1791 CellPos
aPos( nCol
, nRow
);
1792 findMergeOrigin( aPos
);
1793 if( (aPos
.mnCol
< rFirst
.mnCol
) || (aPos
.mnRow
< rFirst
.mnRow
) )
1795 rFirst
.mnCol
= std::min( rFirst
.mnCol
, aPos
.mnCol
);
1796 rFirst
.mnRow
= std::min( rFirst
.mnRow
, aPos
.mnRow
);
1802 if( ((nCol
+ xCell
->getColumnSpan() - 1) > rLast
.mnCol
) || (nRow
+ xCell
->getRowSpan() - 1 ) > rLast
.mnRow
)
1804 rLast
.mnCol
= std::max( rLast
.mnCol
, nCol
+ xCell
->getColumnSpan() - 1 );
1805 rLast
.mnRow
= std::max( rLast
.mnRow
, nRow
+ xCell
->getRowSpan() - 1 );
1814 else if( mpView
&& mpView
->IsTextEdit() )
1816 rFirst
= getSelectionStart();
1817 findMergeOrigin( rFirst
);
1822 Reference
< XMergeableCell
> xCell( mxTable
->getCellByPosition( rLast
.mnCol
, rLast
.mnRow
), UNO_QUERY
);
1825 rLast
.mnCol
+= xCell
->getColumnSpan() - 1;
1826 rLast
.mnRow
+= xCell
->getRowSpan() - 1;
1836 rLast
.mnRow
= mxTable
->getRowCount()-1;
1837 rLast
.mnCol
= mxTable
->getColumnCount()-1;
1849 void SvxTableController::StartSelection( const CellPos
& rPos
)
1852 mbCellSelectionMode
= true;
1853 maCursorLastPos
= maCursorFirstPos
= rPos
;
1854 mpView
->MarkListHasChanged();
1859 void SvxTableController::setSelectedCells( const CellPos
& rStart
, const CellPos
& rEnd
)
1862 mbCellSelectionMode
= true;
1863 maCursorFirstPos
= rStart
;
1864 UpdateSelection( rEnd
);
1869 void SvxTableController::UpdateSelection( const CellPos
& rPos
)
1871 maCursorLastPos
= rPos
;
1872 mpView
->MarkListHasChanged();
1877 void SvxTableController::clearSelection()
1884 void SvxTableController::selectAll()
1888 CellPos aPos1
, aPos2( mxTable
->getColumnCount()-1, mxTable
->getRowCount()-1 );
1889 if( (aPos2
.mnCol
>= 0) && (aPos2
.mnRow
>= 0) )
1891 setSelectedCells( aPos1
, aPos2
);
1898 void SvxTableController::RemoveSelection()
1900 if( mbCellSelectionMode
)
1902 mbCellSelectionMode
= false;
1903 mpView
->MarkListHasChanged();
1909 void SvxTableController::onTableModified()
1911 if( mnUpdateEvent
== 0 )
1912 mnUpdateEvent
= Application::PostUserEvent( LINK( this, SvxTableController
, UpdateHdl
) );
1916 void SvxTableController::updateSelectionOverlay()
1918 destroySelectionOverlay();
1919 if( mbCellSelectionMode
)
1921 ::sdr::table::SdrTableObj
* pTableObj
= dynamic_cast< ::sdr::table::SdrTableObj
* >( mxTableObj
.get() );
1924 sdr::overlay::OverlayObjectCell::RangeVector aRanges
;
1927 CellPos aStart
,aEnd
;
1928 getSelectedCells( aStart
, aEnd
);
1929 pTableObj
->getCellBounds( aStart
, aRect
);
1931 basegfx::B2DRange
a2DRange( basegfx::B2DPoint(aRect
.Left(), aRect
.Top()) );
1932 a2DRange
.expand( basegfx::B2DPoint(aRect
.Right(), aRect
.Bottom()) );
1934 findMergeOrigin( aEnd
);
1935 pTableObj
->getCellBounds( aEnd
, aRect
);
1936 a2DRange
.expand( basegfx::B2DPoint(aRect
.Left(), aRect
.Top()) );
1937 a2DRange
.expand( basegfx::B2DPoint(aRect
.Right(), aRect
.Bottom()) );
1938 aRanges
.push_back( a2DRange
);
1940 ::Color
aHighlight( COL_BLUE
);
1941 OutputDevice
* pOutDev
= mpView
->GetFirstOutputDevice();
1943 aHighlight
= pOutDev
->GetSettings().GetStyleSettings().GetHighlightColor();
1945 const sal_uInt32 nCount
= mpView
->PaintWindowCount();
1946 for( sal_uInt32 nIndex
= 0; nIndex
< nCount
; nIndex
++ )
1948 SdrPaintWindow
* pPaintWindow
= mpView
->GetPaintWindow(nIndex
);
1951 rtl::Reference
< ::sdr::overlay::OverlayManager
> xOverlayManager
= pPaintWindow
->GetOverlayManager();
1952 if( xOverlayManager
.is() )
1954 // sdr::overlay::CellOverlayType eType = sdr::overlay::CELL_OVERLAY_INVERT;
1955 sdr::overlay::CellOverlayType eType
= sdr::overlay::CELL_OVERLAY_TRANSPARENT
;
1957 sdr::overlay::OverlayObjectCell
* pOverlay
= new sdr::overlay::OverlayObjectCell( eType
, aHighlight
, aRanges
);
1959 xOverlayManager
->add(*pOverlay
);
1960 mpSelectionOverlay
= new ::sdr::overlay::OverlayObjectList
;
1961 mpSelectionOverlay
->append(*pOverlay
);
1971 void SvxTableController::destroySelectionOverlay()
1973 if( mpSelectionOverlay
)
1975 delete mpSelectionOverlay
;
1976 mpSelectionOverlay
= 0;
1982 void SvxTableController::MergeAttrFromSelectedCells(SfxItemSet
& rAttr
, bool bOnlyHardAttr
) const
1986 CellPos aStart
, aEnd
;
1987 const_cast<SvxTableController
&>(*this).getSelectedCells( aStart
, aEnd
);
1989 for( sal_Int32 nRow
= aStart
.mnRow
; nRow
<= aEnd
.mnRow
; nRow
++ )
1991 for( sal_Int32 nCol
= aStart
.mnCol
; nCol
<= aEnd
.mnCol
; nCol
++ )
1993 CellRef
xCell( dynamic_cast< Cell
* >( mxTable
->getCellByPosition( nCol
, nRow
).get() ) );
1994 if( xCell
.is() && !xCell
->isMerged() )
1996 const SfxItemSet
& rSet
= xCell
->GetItemSet();
1997 SfxWhichIter
aIter(rSet
);
1998 sal_uInt16
nWhich(aIter
.FirstWhich());
2003 if(SFX_ITEM_DONTCARE
== rSet
.GetItemState(nWhich
, false))
2004 rAttr
.InvalidateItem(nWhich
);
2006 rAttr
.MergeValue(rSet
.Get(nWhich
), true);
2008 else if(SFX_ITEM_SET
== rSet
.GetItemState(nWhich
, false))
2010 const SfxPoolItem
& rItem
= rSet
.Get(nWhich
);
2011 rAttr
.MergeValue(rItem
, true);
2014 nWhich
= aIter
.NextWhich();
2024 const sal_uInt16 CELL_BEFORE
= 0x0001;
2025 const sal_uInt16 CELL_LEFT
= 0x0002;
2026 const sal_uInt16 CELL_RIGHT
= 0x0004;
2027 const sal_uInt16 CELL_AFTER
= 0x0008;
2029 const sal_uInt16 CELL_UPPER
= 0x0010;
2030 const sal_uInt16 CELL_TOP
= 0x0020;
2031 const sal_uInt16 CELL_BOTTOM
= 0x0040;
2032 const sal_uInt16 CELL_LOWER
= 0x0080;
2036 static void ImplSetLinePreserveColor( SvxBoxItem
& rNewFrame
, const SvxBorderLine
* pNew
, sal_uInt16 nLine
)
2040 const SvxBorderLine
* pOld
= rNewFrame
.GetLine(nLine
);
2043 SvxBorderLine
aNewLine( *pNew
);
2044 aNewLine
.SetColor( pOld
->GetColor() );
2045 rNewFrame
.SetLine( &aNewLine
, nLine
);
2049 rNewFrame
.SetLine( pNew
, nLine
);
2054 static void ImplApplyBoxItem( sal_uInt16 nCellFlags
, const SvxBoxItem
* pBoxItem
, const SvxBoxInfoItem
* pBoxInfoItem
, SvxBoxItem
& rNewFrame
)
2056 if( (nCellFlags
& (CELL_BEFORE
|CELL_AFTER
|CELL_UPPER
|CELL_LOWER
)) != 0 )
2058 // current cell is outside the selection
2060 if( (nCellFlags
& ( CELL_BEFORE
|CELL_AFTER
)) == 0 ) // check if its not nw or ne corner
2062 if( nCellFlags
& CELL_UPPER
)
2064 if( pBoxInfoItem
->IsValid(VALID_TOP
) )
2065 rNewFrame
.SetLine(0, BOX_LINE_BOTTOM
);
2067 else if( nCellFlags
& CELL_LOWER
)
2069 if( pBoxInfoItem
->IsValid(VALID_BOTTOM
) )
2070 rNewFrame
.SetLine( 0, BOX_LINE_TOP
);
2073 else if( (nCellFlags
& ( CELL_UPPER
|CELL_LOWER
)) == 0 ) // check if its not sw or se corner
2075 if( nCellFlags
& CELL_BEFORE
)
2077 if( pBoxInfoItem
->IsValid(VALID_LEFT
) )
2078 rNewFrame
.SetLine( 0, BOX_LINE_RIGHT
);
2080 else if( nCellFlags
& CELL_AFTER
)
2082 if( pBoxInfoItem
->IsValid(VALID_RIGHT
) )
2083 rNewFrame
.SetLine( 0, BOX_LINE_LEFT
);
2089 // current cell is inside the selection
2091 if( (nCellFlags
& CELL_LEFT
) ? pBoxInfoItem
->IsValid(VALID_LEFT
) : pBoxInfoItem
->IsValid(VALID_VERT
) )
2092 rNewFrame
.SetLine( (nCellFlags
& CELL_LEFT
) ? pBoxItem
->GetLeft() : pBoxInfoItem
->GetVert(), BOX_LINE_LEFT
);
2094 if( (nCellFlags
& CELL_RIGHT
) ? pBoxInfoItem
->IsValid(VALID_RIGHT
) : pBoxInfoItem
->IsValid(VALID_VERT
) )
2095 rNewFrame
.SetLine( (nCellFlags
& CELL_RIGHT
) ? pBoxItem
->GetRight() : pBoxInfoItem
->GetVert(), BOX_LINE_RIGHT
);
2097 if( (nCellFlags
& CELL_TOP
) ? pBoxInfoItem
->IsValid(VALID_TOP
) : pBoxInfoItem
->IsValid(VALID_HORI
) )
2098 rNewFrame
.SetLine( (nCellFlags
& CELL_TOP
) ? pBoxItem
->GetTop() : pBoxInfoItem
->GetHori(), BOX_LINE_TOP
);
2100 if( (nCellFlags
& CELL_BOTTOM
) ? pBoxInfoItem
->IsValid(VALID_BOTTOM
) : pBoxInfoItem
->IsValid(VALID_HORI
) )
2101 rNewFrame
.SetLine( (nCellFlags
& CELL_BOTTOM
) ? pBoxItem
->GetBottom() : pBoxInfoItem
->GetHori(), BOX_LINE_BOTTOM
);
2103 // apply distance to borders
2104 if( pBoxInfoItem
->IsValid( VALID_DISTANCE
) )
2105 for( sal_uInt16 nLine
= 0; nLine
< 4; ++nLine
)
2106 rNewFrame
.SetDistance( pBoxItem
->GetDistance( nLine
), nLine
);
2112 static void ImplSetLineColor( SvxBoxItem
& rNewFrame
, sal_uInt16 nLine
, const Color
& rColor
)
2114 const SvxBorderLine
* pSourceLine
= rNewFrame
.GetLine( nLine
);
2117 SvxBorderLine
aLine( *pSourceLine
);
2118 aLine
.SetColor( rColor
);
2119 rNewFrame
.SetLine( &aLine
, nLine
);
2125 static void ImplApplyLineColorItem( sal_uInt16 nCellFlags
, const SvxColorItem
* pLineColorItem
, SvxBoxItem
& rNewFrame
)
2127 const Color
aColor( pLineColorItem
->GetValue() );
2129 if( (nCellFlags
& (CELL_LOWER
|CELL_BEFORE
|CELL_AFTER
)) == 0 )
2130 ImplSetLineColor( rNewFrame
, BOX_LINE_BOTTOM
, aColor
);
2132 if( (nCellFlags
& (CELL_UPPER
|CELL_BEFORE
|CELL_AFTER
)) == 0 )
2133 ImplSetLineColor( rNewFrame
, BOX_LINE_TOP
, aColor
);
2135 if( (nCellFlags
& (CELL_UPPER
|CELL_LOWER
|CELL_AFTER
)) == 0 )
2136 ImplSetLineColor( rNewFrame
, BOX_LINE_RIGHT
, aColor
);
2138 if( (nCellFlags
& (CELL_UPPER
|CELL_LOWER
|CELL_BEFORE
)) == 0 )
2139 ImplSetLineColor( rNewFrame
, BOX_LINE_LEFT
, aColor
);
2144 static void ImplApplyBorderLineItem( sal_uInt16 nCellFlags
, const SvxBorderLine
* pBorderLineItem
, SvxBoxItem
& rNewFrame
)
2146 if( (nCellFlags
& ( CELL_BEFORE
|CELL_AFTER
|CELL_UPPER
|CELL_LOWER
)) != 0 )
2148 if( (nCellFlags
& ( CELL_BEFORE
|CELL_AFTER
)) == 0 ) // check if its not nw or ne corner
2150 if( nCellFlags
& CELL_UPPER
)
2152 if( rNewFrame
.GetBottom() )
2153 ImplSetLinePreserveColor( rNewFrame
, pBorderLineItem
, BOX_LINE_BOTTOM
);
2155 else if( nCellFlags
& CELL_LOWER
)
2157 if( rNewFrame
.GetTop() )
2158 ImplSetLinePreserveColor( rNewFrame
, pBorderLineItem
, BOX_LINE_TOP
);
2161 else if( (nCellFlags
& ( CELL_UPPER
|CELL_LOWER
)) == 0 ) // check if its not sw or se corner
2163 if( nCellFlags
& CELL_BEFORE
)
2165 if( rNewFrame
.GetRight() )
2166 ImplSetLinePreserveColor( rNewFrame
, pBorderLineItem
, BOX_LINE_RIGHT
);
2168 else if( nCellFlags
& CELL_AFTER
)
2170 if( rNewFrame
.GetLeft() )
2171 ImplSetLinePreserveColor( rNewFrame
, pBorderLineItem
, BOX_LINE_LEFT
);
2177 if( rNewFrame
.GetBottom() )
2178 ImplSetLinePreserveColor( rNewFrame
, pBorderLineItem
, BOX_LINE_BOTTOM
);
2179 if( rNewFrame
.GetTop() )
2180 ImplSetLinePreserveColor( rNewFrame
, pBorderLineItem
, BOX_LINE_TOP
);
2181 if( rNewFrame
.GetRight() )
2182 ImplSetLinePreserveColor( rNewFrame
, pBorderLineItem
, BOX_LINE_RIGHT
);
2183 if( rNewFrame
.GetLeft() )
2184 ImplSetLinePreserveColor( rNewFrame
, pBorderLineItem
, BOX_LINE_LEFT
);
2190 void SvxTableController::ApplyBorderAttr( const SfxItemSet
& rAttr
)
2194 const sal_Int32 nRowCount
= mxTable
->getRowCount();
2195 const sal_Int32 nColCount
= mxTable
->getColumnCount();
2196 if( nRowCount
&& nColCount
)
2198 const SvxBoxItem
* pBoxItem
= 0;
2199 if(SFX_ITEM_SET
== rAttr
.GetItemState(SDRATTR_TABLE_BORDER
, false) )
2200 pBoxItem
= dynamic_cast< const SvxBoxItem
* >( &rAttr
.Get( SDRATTR_TABLE_BORDER
) );
2202 const SvxBoxInfoItem
* pBoxInfoItem
= 0;
2203 if(SFX_ITEM_SET
== rAttr
.GetItemState(SDRATTR_TABLE_BORDER_INNER
, false) )
2204 pBoxInfoItem
= dynamic_cast< const SvxBoxInfoItem
* >( &rAttr
.Get( SDRATTR_TABLE_BORDER_INNER
) );
2206 const SvxColorItem
* pLineColorItem
= 0;
2207 if(SFX_ITEM_SET
== rAttr
.GetItemState(SID_FRAME_LINECOLOR
, false) )
2208 pLineColorItem
= dynamic_cast< const SvxColorItem
* >( &rAttr
.Get( SID_FRAME_LINECOLOR
) );
2210 const SvxBorderLine
* pBorderLineItem
= 0;
2211 if(SFX_ITEM_SET
== rAttr
.GetItemState(SID_FRAME_LINESTYLE
, false) )
2212 pBorderLineItem
= ((const SvxLineItem
&)rAttr
.Get( SID_FRAME_LINESTYLE
)).GetLine();
2214 if( pBoxInfoItem
&& !pBoxItem
)
2216 const static SvxBoxItem
gaEmptyBoxItem( SDRATTR_TABLE_BORDER
);
2217 pBoxItem
= &gaEmptyBoxItem
;
2219 else if( pBoxItem
&& !pBoxInfoItem
)
2221 const static SvxBoxInfoItem
gaEmptyBoxInfoItem( SDRATTR_TABLE_BORDER_INNER
);
2222 pBoxInfoItem
= &gaEmptyBoxInfoItem
;
2225 CellPos aStart
, aEnd
;
2226 getSelectedCells( aStart
, aEnd
);
2228 const sal_Int32 nLastRow
= std::min( aEnd
.mnRow
+ 2, nRowCount
);
2229 const sal_Int32 nLastCol
= std::min( aEnd
.mnCol
+ 2, nColCount
);
2231 for( sal_Int32 nRow
= std::max( aStart
.mnRow
- 1, (sal_Int32
)0 ); nRow
< nLastRow
; nRow
++ )
2233 sal_uInt16 nRowFlags
= 0;
2234 nRowFlags
|= (nRow
== aStart
.mnRow
) ? CELL_TOP
: 0;
2235 nRowFlags
|= (nRow
== aEnd
.mnRow
) ? CELL_BOTTOM
: 0;
2236 nRowFlags
|= (nRow
< aStart
.mnRow
) ? CELL_UPPER
: 0;
2237 nRowFlags
|= (nRow
> aEnd
.mnRow
) ? CELL_LOWER
: 0;
2239 for( sal_Int32 nCol
= std::max( aStart
.mnCol
- 1, (sal_Int32
)0 ); nCol
< nLastCol
; nCol
++ )
2241 CellRef
xCell( dynamic_cast< Cell
* >( mxTable
->getCellByPosition( nCol
, nRow
).get() ) );
2245 const SfxItemSet
& rSet
= xCell
->GetItemSet();
2246 const SvxBoxItem
* pOldOuter
= (const SvxBoxItem
*) &rSet
.Get( SDRATTR_TABLE_BORDER
);
2248 SvxBoxItem
aNewFrame( *pOldOuter
);
2250 sal_uInt16 nCellFlags
= nRowFlags
;
2251 nCellFlags
|= (nCol
== aStart
.mnCol
) ? CELL_LEFT
: 0;
2252 nCellFlags
|= (nCol
== aEnd
.mnCol
) ? CELL_RIGHT
: 0;
2253 nCellFlags
|= (nCol
< aStart
.mnCol
) ? CELL_BEFORE
: 0;
2254 nCellFlags
|= (nCol
> aEnd
.mnCol
) ? CELL_AFTER
: 0;
2256 if( pBoxItem
&& pBoxInfoItem
)
2257 ImplApplyBoxItem( nCellFlags
, pBoxItem
, pBoxInfoItem
, aNewFrame
);
2259 if( pLineColorItem
)
2260 ImplApplyLineColorItem( nCellFlags
, pLineColorItem
, aNewFrame
);
2262 if( pBorderLineItem
)
2263 ImplApplyBorderLineItem( nCellFlags
, pBorderLineItem
, aNewFrame
);
2265 if (aNewFrame
!= *pOldOuter
)
2267 SfxItemSet
aAttr(*rSet
.GetPool(), rSet
.GetRanges());
2268 aAttr
.Put(aNewFrame
);
2269 xCell
->SetMergedItemSetAndBroadcast( aAttr
, false );
2279 void SvxTableController::UpdateTableShape()
2281 SdrObject
* pTableObj
= mxTableObj
.get();
2284 pTableObj
->ActionChanged();
2285 pTableObj
->BroadcastObjectChange();
2287 updateSelectionOverlay();
2293 void SvxTableController::SetAttrToSelectedCells(const SfxItemSet
& rAttr
, bool bReplaceAll
)
2297 const bool bUndo
= mpModel
&& mpModel
->IsUndoEnabled();
2300 mpModel
->BegUndo( ImpGetResStr(STR_TABLE_NUMFORMAT
) );
2302 CellPos aStart
, aEnd
;
2303 getSelectedCells( aStart
, aEnd
);
2305 SfxItemSet
aAttr(*rAttr
.GetPool(), rAttr
.GetRanges());
2306 aAttr
.Put(rAttr
, true);
2308 const bool bFrame
= (rAttr
.GetItemState( SDRATTR_TABLE_BORDER
) == SFX_ITEM_SET
) || (rAttr
.GetItemState( SDRATTR_TABLE_BORDER_INNER
) == SFX_ITEM_SET
);
2312 aAttr
.ClearItem( SDRATTR_TABLE_BORDER
);
2313 aAttr
.ClearItem( SDRATTR_TABLE_BORDER_INNER
);
2316 for( sal_Int32 nRow
= aStart
.mnRow
; nRow
<= aEnd
.mnRow
; nRow
++ )
2318 for( sal_Int32 nCol
= aStart
.mnCol
; nCol
<= aEnd
.mnCol
; nCol
++ )
2320 CellRef
xCell( dynamic_cast< Cell
* >( mxTable
->getCellByPosition( nCol
, nRow
).get() ) );
2325 xCell
->SetMergedItemSetAndBroadcast(aAttr
, bReplaceAll
);
2332 ApplyBorderAttr( rAttr
);
2345 bool SvxTableController::GetAttributes(SfxItemSet
& rTargetSet
, bool bOnlyHardAttr
) const
2347 if( mxTableObj
.is() && hasSelectedCells() )
2349 MergeAttrFromSelectedCells( rTargetSet
, bOnlyHardAttr
);
2351 if( mpView
->IsTextEdit() )
2353 if( mxTableObj
->GetOutlinerParaObject() )
2354 rTargetSet
.Put( SvxScriptTypeItem( mxTableObj
->GetOutlinerParaObject()->GetTextObject().GetScriptType() ) );
2356 OutlinerView
* pTextEditOutlinerView
= mpView
->GetTextEditOutlinerView();
2357 if(pTextEditOutlinerView
)
2359 // FALSE= InvalidItems nicht al Default, sondern als "Loecher" betrachten
2360 rTargetSet
.Put(pTextEditOutlinerView
->GetAttribs(), false);
2361 rTargetSet
.Put( SvxScriptTypeItem( pTextEditOutlinerView
->GetSelectedScriptType() ) );
2375 bool SvxTableController::SetAttributes(const SfxItemSet
& rSet
, bool bReplaceAll
)
2377 if( mbCellSelectionMode
|| mpView
->IsTextEdit() )
2379 SetAttrToSelectedCells( rSet
, bReplaceAll
);
2387 bool SvxTableController::GetMarkedObjModel( SdrPage
* pNewPage
)
2389 if( mxTableObj
.is() && mbCellSelectionMode
&& pNewPage
) try
2391 ::sdr::table::SdrTableObj
& rTableObj
= *static_cast< ::sdr::table::SdrTableObj
* >( mxTableObj
.get() );
2393 CellPos aStart
, aEnd
;
2394 getSelectedCells( aStart
, aEnd
);
2396 SdrTableObj
* pNewTableObj
= rTableObj
.CloneRange( aStart
, aEnd
);
2398 pNewTableObj
->SetPage( pNewPage
);
2399 pNewTableObj
->SetModel( pNewPage
->GetModel() );
2401 SdrInsertReason
aReason(SDRREASON_VIEWCALL
);
2402 pNewPage
->InsertObject(pNewTableObj
,CONTAINER_APPEND
,&aReason
);
2408 OSL_FAIL( "svx::SvxTableController::GetMarkedObjModel(), exception caught!" );
2415 bool SvxTableController::PasteObjModel( const SdrModel
& rModel
)
2417 if( mxTableObj
.is() && mpView
&& (rModel
.GetPageCount() >= 1) )
2419 const SdrPage
* pPastePage
= rModel
.GetPage(0);
2420 if( pPastePage
&& pPastePage
->GetObjCount() == 1 )
2422 SdrTableObj
* pPasteTableObj
= dynamic_cast< SdrTableObj
* >( pPastePage
->GetObj(0) );
2423 if( pPasteTableObj
)
2425 return PasteObject( pPasteTableObj
);
2435 bool SvxTableController::PasteObject( SdrTableObj
* pPasteTableObj
)
2437 if( !pPasteTableObj
)
2440 Reference
< XTable
> xPasteTable( pPasteTableObj
->getTable() );
2441 if( !xPasteTable
.is() )
2447 sal_Int32 nPasteColumns
= xPasteTable
->getColumnCount();
2448 sal_Int32 nPasteRows
= xPasteTable
->getRowCount();
2450 CellPos aStart
, aEnd
;
2451 getSelectedCells( aStart
, aEnd
);
2453 if( mpView
->IsTextEdit() )
2454 mpView
->SdrEndTextEdit(true);
2456 sal_Int32 nColumns
= mxTable
->getColumnCount();
2457 sal_Int32 nRows
= mxTable
->getRowCount();
2459 const sal_Int32 nMissing
= nPasteRows
- ( nRows
- aStart
.mnRow
);
2462 Reference
< XTableRows
> xRows( mxTable
->getRows() );
2463 xRows
->insertByIndex( nRows
, nMissing
);
2464 nRows
= mxTable
->getRowCount();
2467 nPasteRows
= std::min( nPasteRows
, nRows
- aStart
.mnRow
);
2468 nPasteColumns
= std::min( nPasteColumns
, nColumns
- aStart
.mnCol
);
2470 // copy cell contents
2471 for( sal_Int32 nRow
= 0; nRow
< nPasteRows
; ++nRow
)
2473 for( sal_Int32 nCol
= 0; nCol
< nPasteColumns
; ++nCol
)
2475 CellRef
xTargetCell( dynamic_cast< Cell
* >( mxTable
->getCellByPosition( aStart
.mnCol
+ nCol
, aStart
.mnRow
+ nRow
).get() ) );
2476 if( xTargetCell
.is() && !xTargetCell
->isMerged() )
2478 xTargetCell
->AddUndo();
2479 xTargetCell
->cloneFrom( dynamic_cast< Cell
* >( xPasteTable
->getCellByPosition( nCol
, nRow
).get() ) );
2480 nCol
+= xTargetCell
->getColumnSpan() - 1;
2490 bool SvxTableController::TakeFormatPaintBrush( boost::shared_ptr
< SfxItemSet
>& /*rFormatSet*/ )
2492 // SdrView::TakeFormatPaintBrush() is enough
2496 bool SvxTableController::ApplyFormatPaintBrush( SfxItemSet
& rFormatSet
, bool bNoCharacterFormats
, bool bNoParagraphFormats
)
2498 if( mbCellSelectionMode
)
2500 SdrTextObj
* pTableObj
= dynamic_cast<SdrTextObj
*>( mxTableObj
.get() );
2504 const bool bUndo
= mpModel
&& mpModel
->IsUndoEnabled();
2507 mpModel
->BegUndo( ImpGetResStr(STR_TABLE_NUMFORMAT
) );
2509 CellPos aStart
, aEnd
;
2510 getSelectedCells( aStart
, aEnd
);
2512 SfxItemSet
aAttr(*rFormatSet
.GetPool(), rFormatSet
.GetRanges());
2513 aAttr
.Put(rFormatSet
, true);
2515 const bool bFrame
= (rFormatSet
.GetItemState( SDRATTR_TABLE_BORDER
) == SFX_ITEM_SET
) || (rFormatSet
.GetItemState( SDRATTR_TABLE_BORDER_INNER
) == SFX_ITEM_SET
);
2519 aAttr
.ClearItem( SDRATTR_TABLE_BORDER
);
2520 aAttr
.ClearItem( SDRATTR_TABLE_BORDER_INNER
);
2523 const sal_uInt16
* pRanges
= rFormatSet
.GetRanges();
2524 bool bTextOnly
= true;
2528 if( (*pRanges
!= EE_PARA_START
) && (*pRanges
!= EE_CHAR_START
) )
2536 const bool bReplaceAll
= false;
2537 for( sal_Int32 nRow
= aStart
.mnRow
; nRow
<= aEnd
.mnRow
; nRow
++ )
2539 for( sal_Int32 nCol
= aStart
.mnCol
; nCol
<= aEnd
.mnCol
; nCol
++ )
2541 CellRef
xCell( dynamic_cast< Cell
* >( mxTable
->getCellByPosition( nCol
, nRow
).get() ) );
2547 xCell
->SetMergedItemSetAndBroadcast(aAttr
, bReplaceAll
);
2549 SdrText
* pText
= static_cast< SdrText
* >( xCell
.get() );
2550 mpView
->ApplyFormatPaintBrushToText( rFormatSet
, *pTableObj
, pText
, bNoCharacterFormats
, bNoParagraphFormats
);
2557 ApplyBorderAttr( rFormatSet
);
2574 IMPL_LINK_NOARG(SvxTableController
, UpdateHdl
)
2578 if( mbCellSelectionMode
)
2580 CellPos
aStart( maCursorFirstPos
);
2581 CellPos
aEnd( maCursorLastPos
);
2584 if( aStart
!= maCursorFirstPos
|| aEnd
!= maCursorLastPos
)
2586 setSelectedCells( aStart
, aEnd
);
2589 updateSelectionOverlay();
2599 LinesState(SvxBoxItem
& rBoxItem_
, SvxBoxInfoItem
& rBoxInfoItem_
)
2600 : rBoxItem(rBoxItem_
)
2601 , rBoxInfoItem(rBoxInfoItem_
)
2602 , bDistanceIndeterminate(false)
2604 std::fill_n(aBorderSet
, 4, false);
2605 std::fill_n(aInnerLineSet
, 2, false);
2606 std::fill_n(aBorderIndeterminate
, 4, false);
2607 std::fill_n(aInnerLineIndeterminate
, 2, false);
2608 std::fill_n(aDistanceSet
, 4, false);
2609 std::fill_n(aDistance
, 4, 0);
2612 SvxBoxItem
& rBoxItem
;
2613 SvxBoxInfoItem
& rBoxInfoItem
;
2615 bool aInnerLineSet
[2];
2616 bool aBorderIndeterminate
[4];
2617 bool aInnerLineIndeterminate
[2];
2618 bool aDistanceSet
[4];
2619 sal_uInt16 aDistance
[4];
2620 bool bDistanceIndeterminate
;
2623 class BoxItemWrapper
2626 BoxItemWrapper(SvxBoxItem
& rBoxItem
, SvxBoxInfoItem
& rBoxInfoItem
, sal_uInt16 nBorderLine
, sal_uInt16 nInnerLine
, bool bBorder
);
2628 const SvxBorderLine
* getLine() const;
2629 void setLine(const SvxBorderLine
* pLine
);
2632 SvxBoxItem
& m_rBoxItem
;
2633 SvxBoxInfoItem
& m_rBoxInfoItem
;
2634 const sal_uInt16 m_nLine
;
2635 const bool m_bBorder
;
2638 BoxItemWrapper::BoxItemWrapper(
2639 SvxBoxItem
& rBoxItem
, SvxBoxInfoItem
& rBoxInfoItem
,
2640 const sal_uInt16 nBorderLine
, const sal_uInt16 nInnerLine
, const bool bBorder
)
2641 : m_rBoxItem(rBoxItem
)
2642 , m_rBoxInfoItem(rBoxInfoItem
)
2643 , m_nLine(bBorder
? nBorderLine
: nInnerLine
)
2644 , m_bBorder(bBorder
)
2646 assert(bBorder
? (m_nLine
<= BOX_LINE_RIGHT
) : (m_nLine
<= BOXINFO_LINE_VERT
));
2649 const SvxBorderLine
* BoxItemWrapper::getLine() const
2652 return m_rBoxItem
.GetLine(m_nLine
);
2654 return (m_nLine
== BOXINFO_LINE_HORI
) ? m_rBoxInfoItem
.GetHori() : m_rBoxInfoItem
.GetVert();
2657 void BoxItemWrapper::setLine(const SvxBorderLine
* pLine
)
2660 m_rBoxItem
.SetLine(pLine
, m_nLine
);
2662 m_rBoxInfoItem
.SetLine(pLine
, m_nLine
);
2665 void lcl_MergeBorderLine(
2666 LinesState
& rLinesState
, const SvxBorderLine
* const pLine
, const sal_uInt16 nLine
,
2667 const sal_uInt8 nValidFlag
, const bool bBorder
= true)
2669 const sal_uInt16
nInnerLine(bBorder
? 0 : ((nValidFlag
& VALID_HORI
) ? BOXINFO_LINE_HORI
: BOXINFO_LINE_VERT
));
2670 BoxItemWrapper
aBoxItem(rLinesState
.rBoxItem
, rLinesState
.rBoxInfoItem
, nLine
, nInnerLine
, bBorder
);
2671 bool& rbSet(bBorder
? rLinesState
.aBorderSet
[nLine
] : rLinesState
.aInnerLineSet
[nInnerLine
]);
2672 bool& rbIndeterminate(bBorder
? rLinesState
.aBorderIndeterminate
[nLine
] : rLinesState
.aInnerLineIndeterminate
[nInnerLine
]);
2676 if (!rbIndeterminate
)
2678 const SvxBorderLine
* const pMergedLine(aBoxItem
.getLine());
2679 if ((pLine
&& !pMergedLine
) || (!pLine
&& pMergedLine
) || (pLine
&& (*pLine
!= *pMergedLine
)))
2681 aBoxItem
.setLine(0);
2682 rbIndeterminate
= true;
2688 aBoxItem
.setLine(pLine
);
2693 void lcl_MergeBorderOrInnerLine(
2694 LinesState
& rLinesState
, const SvxBorderLine
* const pLine
, const sal_uInt16 nLine
,
2695 const sal_uInt8 nValidFlag
, const bool bBorder
)
2698 lcl_MergeBorderLine(rLinesState
, pLine
, nLine
, nValidFlag
);
2701 const bool bVertical
= (nLine
== BOX_LINE_LEFT
) || (nLine
== BOX_LINE_RIGHT
);
2702 lcl_MergeBorderLine(rLinesState
, pLine
, nLine
, bVertical
? VALID_VERT
: VALID_HORI
, false);
2706 void lcl_MergeDistance(
2707 LinesState
& rLinesState
, const sal_uInt16 nIndex
, const sal_uInt16 nDistance
)
2709 if (rLinesState
.aDistanceSet
[nIndex
])
2711 if (!rLinesState
.bDistanceIndeterminate
)
2712 rLinesState
.bDistanceIndeterminate
= nDistance
!= rLinesState
.aDistance
[nIndex
];
2716 rLinesState
.aDistance
[nIndex
] = nDistance
;
2717 rLinesState
.aDistanceSet
[nIndex
] = true;
2721 void lcl_MergeCommonBorderAttr(LinesState
& rLinesState
, const SvxBoxItem
& rCellBoxItem
, const sal_Int32 nCellFlags
)
2723 if( (nCellFlags
& (CELL_BEFORE
|CELL_AFTER
|CELL_UPPER
|CELL_LOWER
)) != 0 )
2725 // current cell is outside the selection
2727 if( (nCellFlags
& ( CELL_BEFORE
|CELL_AFTER
)) == 0 ) // check if its not nw or ne corner
2729 if( nCellFlags
& CELL_UPPER
)
2730 lcl_MergeBorderLine(rLinesState
, rCellBoxItem
.GetBottom(), BOX_LINE_TOP
, VALID_TOP
);
2731 else if( nCellFlags
& CELL_LOWER
)
2732 lcl_MergeBorderLine(rLinesState
, rCellBoxItem
.GetTop(), BOX_LINE_BOTTOM
, VALID_BOTTOM
);
2734 else if( (nCellFlags
& ( CELL_UPPER
|CELL_LOWER
)) == 0 ) // check if its not sw or se corner
2736 if( nCellFlags
& CELL_BEFORE
)
2737 lcl_MergeBorderLine(rLinesState
, rCellBoxItem
.GetRight(), BOX_LINE_LEFT
, VALID_LEFT
);
2738 else if( nCellFlags
& CELL_AFTER
)
2739 lcl_MergeBorderLine(rLinesState
, rCellBoxItem
.GetLeft(), BOX_LINE_RIGHT
, VALID_RIGHT
);
2742 // NOTE: inner distances for cells outside the selected range
2743 // are not relevant -> we ignore them.
2747 // current cell is inside the selection
2749 lcl_MergeBorderOrInnerLine(rLinesState
, rCellBoxItem
.GetTop(), BOX_LINE_TOP
, VALID_TOP
, (nCellFlags
& CELL_TOP
) != 0);
2750 lcl_MergeBorderOrInnerLine(rLinesState
, rCellBoxItem
.GetBottom(), BOX_LINE_BOTTOM
, VALID_BOTTOM
, (nCellFlags
& CELL_BOTTOM
) != 0);
2751 lcl_MergeBorderOrInnerLine(rLinesState
, rCellBoxItem
.GetLeft(), BOX_LINE_LEFT
, VALID_LEFT
, (nCellFlags
& CELL_LEFT
) != 0);
2752 lcl_MergeBorderOrInnerLine(rLinesState
, rCellBoxItem
.GetRight(), BOX_LINE_RIGHT
, VALID_RIGHT
, (nCellFlags
& CELL_RIGHT
) != 0);
2754 lcl_MergeDistance(rLinesState
, BOX_LINE_TOP
, rCellBoxItem
.GetDistance(BOX_LINE_TOP
));
2755 lcl_MergeDistance(rLinesState
, BOX_LINE_BOTTOM
, rCellBoxItem
.GetDistance(BOX_LINE_BOTTOM
));
2756 lcl_MergeDistance(rLinesState
, BOX_LINE_LEFT
, rCellBoxItem
.GetDistance(BOX_LINE_LEFT
));
2757 lcl_MergeDistance(rLinesState
, BOX_LINE_RIGHT
, rCellBoxItem
.GetDistance(BOX_LINE_RIGHT
));
2763 void SvxTableController::FillCommonBorderAttrFromSelectedCells( SvxBoxItem
& rBoxItem
, SvxBoxInfoItem
& rBoxInfoItem
) const
2767 const sal_Int32 nRowCount
= mxTable
->getRowCount();
2768 const sal_Int32 nColCount
= mxTable
->getColumnCount();
2769 if( nRowCount
&& nColCount
)
2771 CellPos aStart
, aEnd
;
2772 const_cast< SvxTableController
* >( this )->getSelectedCells( aStart
, aEnd
);
2774 // We are adding one more row/column around the block of selected cells.
2775 // We will be checking the adjoining border of these too.
2776 const sal_Int32 nLastRow
= std::min( aEnd
.mnRow
+ 2, nRowCount
);
2777 const sal_Int32 nLastCol
= std::min( aEnd
.mnCol
+ 2, nColCount
);
2779 rBoxInfoItem
.SetValid( sal_uInt8( ~0 ), false );
2780 LinesState
aLinesState( rBoxItem
, rBoxInfoItem
);
2782 /* Here we go through all the selected cells (enhanced by
2783 * the adjoining row/column on each side) and determine the
2784 * lines for presentation. The algorithm is simple:
2785 * 1. if a border or inner line is set (or unset) in all
2786 * cells to the same value, it will be used.
2787 * 2. if a border or inner line is set only in some cells,
2788 * it will be set to indeterminate state (SetValid() on
2791 for( sal_Int32 nRow
= std::max( aStart
.mnRow
- 1, (sal_Int32
)0 ); nRow
< nLastRow
; nRow
++ )
2793 sal_uInt16 nRowFlags
= 0;
2794 nRowFlags
|= (nRow
== aStart
.mnRow
) ? CELL_TOP
: 0;
2795 nRowFlags
|= (nRow
== aEnd
.mnRow
) ? CELL_BOTTOM
: 0;
2796 nRowFlags
|= (nRow
< aStart
.mnRow
) ? CELL_UPPER
: 0;
2797 nRowFlags
|= (nRow
> aEnd
.mnRow
) ? CELL_LOWER
: 0;
2799 for( sal_Int32 nCol
= std::max( aStart
.mnCol
- 1, (sal_Int32
)0 ); nCol
< nLastCol
; nCol
++ )
2801 CellRef
xCell( dynamic_cast< Cell
* >( mxTable
->getCellByPosition( nCol
, nRow
).get() ) );
2805 sal_uInt16 nCellFlags
= nRowFlags
;
2806 nCellFlags
|= (nCol
== aStart
.mnCol
) ? CELL_LEFT
: 0;
2807 nCellFlags
|= (nCol
== aEnd
.mnCol
) ? CELL_RIGHT
: 0;
2808 nCellFlags
|= (nCol
< aStart
.mnCol
) ? CELL_BEFORE
: 0;
2809 nCellFlags
|= (nCol
> aEnd
.mnCol
) ? CELL_AFTER
: 0;
2811 const SfxItemSet
& rSet
= xCell
->GetItemSet();
2812 const SvxBoxItem
& rCellBoxItem
= static_cast< const SvxBoxItem
& >( rSet
.Get(SDRATTR_TABLE_BORDER
) );
2813 lcl_MergeCommonBorderAttr( aLinesState
, rCellBoxItem
, nCellFlags
);
2817 if (!aLinesState
.aBorderIndeterminate
[BOX_LINE_TOP
])
2818 aLinesState
.rBoxInfoItem
.SetValid(VALID_TOP
);
2819 if (!aLinesState
.aBorderIndeterminate
[BOX_LINE_BOTTOM
])
2820 aLinesState
.rBoxInfoItem
.SetValid(VALID_BOTTOM
);
2821 if (!aLinesState
.aBorderIndeterminate
[BOX_LINE_LEFT
])
2822 aLinesState
.rBoxInfoItem
.SetValid(VALID_LEFT
);
2823 if (!aLinesState
.aBorderIndeterminate
[BOX_LINE_RIGHT
])
2824 aLinesState
.rBoxInfoItem
.SetValid(VALID_RIGHT
);
2825 if (!aLinesState
.aInnerLineIndeterminate
[BOXINFO_LINE_HORI
])
2826 aLinesState
.rBoxInfoItem
.SetValid(VALID_HORI
);
2827 if (!aLinesState
.aInnerLineIndeterminate
[BOXINFO_LINE_VERT
])
2828 aLinesState
.rBoxInfoItem
.SetValid(VALID_VERT
);
2830 if (!aLinesState
.bDistanceIndeterminate
)
2832 if (aLinesState
.aDistanceSet
[BOX_LINE_TOP
])
2833 aLinesState
.rBoxItem
.SetDistance(aLinesState
.aDistance
[BOX_LINE_TOP
], BOX_LINE_TOP
);
2834 if (aLinesState
.aDistanceSet
[BOX_LINE_BOTTOM
])
2835 aLinesState
.rBoxItem
.SetDistance(aLinesState
.aDistance
[BOX_LINE_BOTTOM
], BOX_LINE_BOTTOM
);
2836 if (aLinesState
.aDistanceSet
[BOX_LINE_LEFT
])
2837 aLinesState
.rBoxItem
.SetDistance(aLinesState
.aDistance
[BOX_LINE_LEFT
], BOX_LINE_LEFT
);
2838 if (aLinesState
.aDistanceSet
[BOX_LINE_RIGHT
])
2839 aLinesState
.rBoxItem
.SetDistance(aLinesState
.aDistance
[BOX_LINE_RIGHT
], BOX_LINE_RIGHT
);
2840 aLinesState
.rBoxInfoItem
.SetValid(VALID_DISTANCE
);
2846 bool SvxTableController::selectRow( sal_Int32 row
)
2850 CellPos
aStart( 0, row
), aEnd( mxTable
->getColumnCount() - 1, row
);
2851 StartSelection( aEnd
);
2852 gotoCell( aStart
, true, 0 );
2856 bool SvxTableController::selectColumn( sal_Int32 column
)
2860 CellPos
aStart( column
, 0 ), aEnd( column
, mxTable
->getRowCount() - 1 );
2861 StartSelection( aEnd
);
2862 gotoCell( aStart
, true, 0 );
2866 bool SvxTableController::deselectRow( sal_Int32 row
)
2870 CellPos
aStart( 0, row
), aEnd( mxTable
->getColumnCount() - 1, row
);
2871 StartSelection( aEnd
);
2872 gotoCell( aStart
, false, 0 );
2876 bool SvxTableController::deselectColumn( sal_Int32 column
)
2880 CellPos
aStart( column
, 0 ), aEnd( column
, mxTable
->getRowCount() - 1 );
2881 StartSelection( aEnd
);
2882 gotoCell( aStart
, false, 0 );
2886 bool SvxTableController::isRowSelected( sal_Int32 nRow
)
2888 if( hasSelectedCells() )
2890 CellPos aFirstPos
, aLastPos
;
2891 getSelectedCells( aFirstPos
, aLastPos
);
2892 if( (aFirstPos
.mnCol
== 0) && (nRow
>= aFirstPos
.mnRow
&& nRow
<= aLastPos
.mnRow
) && (mxTable
->getColumnCount() - 1 == aLastPos
.mnCol
) )
2898 bool SvxTableController::isColumnSelected( sal_Int32 nColumn
)
2900 if( hasSelectedCells() )
2902 CellPos aFirstPos
, aLastPos
;
2903 getSelectedCells( aFirstPos
, aLastPos
);
2904 if( (aFirstPos
.mnRow
== 0) && (nColumn
>= aFirstPos
.mnCol
&& nColumn
<= aLastPos
.mnCol
) && (mxTable
->getRowCount() - 1 == aLastPos
.mnRow
) )
2910 bool SvxTableController::isRowHeader()
2912 SdrTableObj
* pTableObj
= dynamic_cast< ::sdr::table::SdrTableObj
* >( mxTableObj
.get() );
2913 SdrModel
* pModel
= pTableObj
? pTableObj
->GetModel() : 0;
2915 if( !pTableObj
|| !pModel
)
2918 TableStyleSettings
aSettings( pTableObj
->getTableStyleSettings() );
2920 return aSettings
.mbUseFirstRow
;
2923 bool SvxTableController::isColumnHeader()
2925 SdrTableObj
* pTableObj
= dynamic_cast< ::sdr::table::SdrTableObj
* >( mxTableObj
.get() );
2926 SdrModel
* pModel
= pTableObj
? pTableObj
->GetModel() : 0;
2928 if( !pTableObj
|| !pModel
)
2931 TableStyleSettings
aSettings( pTableObj
->getTableStyleSettings() );
2933 return aSettings
.mbUseFirstColumn
;
2937 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */