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 .
21 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
22 #include <com/sun/star/container/XNamed.hpp>
23 #include <com/sun/star/container/XNameAccess.hpp>
24 #include <com/sun/star/container/XIndexAccess.hpp>
25 #include <vcl/canvastools.hxx>
26 #include <vcl/ptrstyle.hxx>
27 #include <com/sun/star/style/XStyle.hpp>
28 #include <com/sun/star/beans/XPropertySet.hpp>
29 #include <basegfx/polygon/b2dpolygontools.hxx>
30 #include <basegfx/polygon/b2dpolypolygon.hxx>
31 #include <basegfx/polygon/b2dpolygon.hxx>
32 #include <svl/style.hxx>
33 #include <editeng/editstat.hxx>
34 #include <editeng/outlobj.hxx>
35 #include <svx/svdview.hxx>
36 #include <sdr/properties/textproperties.hxx>
37 #include <svx/svdotable.hxx>
38 #include <svx/svdhdl.hxx>
39 #include "viewcontactoftableobj.hxx"
40 #include <svx/svdoutl.hxx>
41 #include <svx/svddrag.hxx>
42 #include <svx/svdpagv.hxx>
43 #include <tablemodel.hxx>
45 #include <svx/xflclit.hxx>
46 #include "tablelayouter.hxx"
47 #include <svx/svdetc.hxx>
48 #include "tablehandles.hxx"
49 #include <editeng/boxitem.hxx>
50 #include <svx/framelink.hxx>
51 #include <svx/sdr/table/tabledesign.hxx>
52 #include <svx/svdundo.hxx>
53 #include <svx/strings.hrc>
54 #include <svx/dialmgr.hxx>
55 #include <editeng/writingmodeitem.hxx>
56 #include <editeng/frmdiritem.hxx>
57 #include <svx/xflhtit.hxx>
58 #include <svx/xflftrit.hxx>
59 #include <svx/xfltrit.hxx>
60 #include <cppuhelper/implbase.hxx>
61 #include <libxml/xmlwriter.h>
63 #include <boost/property_tree/json_parser.hpp>
65 using ::com::sun::star::uno::Any
;
66 using ::com::sun::star::uno::Reference
;
67 using ::com::sun::star::uno::UNO_QUERY
;
68 using ::com::sun::star::uno::UNO_QUERY_THROW
;
69 using ::com::sun::star::uno::Exception
;
70 using ::com::sun::star::container::XIndexAccess
;
71 using ::com::sun::star::style::XStyle
;
72 using ::com::sun::star::table::XTableRows
;
73 using ::com::sun::star::table::XTableColumns
;
74 using ::com::sun::star::table::XTable
;
75 using ::com::sun::star::beans::XPropertySet
;
76 using ::com::sun::star::util::XModifyBroadcaster
;
77 using sdr::properties::TextProperties
;
78 using sdr::properties::BaseProperties
;
79 using namespace ::com::sun::star
;
80 using namespace ::com::sun::star::text
;
81 using namespace ::com::sun::star::container
;
82 using namespace ::com::sun::star::style
;
84 namespace sdr
{ namespace table
{
86 class TableProperties
: public TextProperties
89 // create a new itemset
90 std::unique_ptr
<SfxItemSet
> CreateObjectSpecificItemSet(SfxItemPool
& rPool
) override
;
94 explicit TableProperties(SdrObject
& rObj
);
96 // constructor for copying, but using new object
97 TableProperties(const TableProperties
& rProps
, SdrObject
& rObj
);
99 // Clone() operator, normally just calls the local copy constructor
100 std::unique_ptr
<BaseProperties
> Clone(SdrObject
& rObj
) const override
;
102 virtual void ItemChange(const sal_uInt16 nWhich
, const SfxPoolItem
* pNewItem
= nullptr) override
;
105 TableProperties::TableProperties(SdrObject
& rObj
)
106 : TextProperties(rObj
)
110 TableProperties::TableProperties(const TableProperties
& rProps
, SdrObject
& rObj
)
111 : TextProperties(rProps
, rObj
)
115 std::unique_ptr
<BaseProperties
> TableProperties::Clone(SdrObject
& rObj
) const
117 return std::unique_ptr
<BaseProperties
>(new TableProperties(*this, rObj
));
120 void TableProperties::ItemChange(const sal_uInt16 nWhich
, const SfxPoolItem
* pNewItem
)
122 if( nWhich
== SDRATTR_TEXTDIRECTION
)
123 AttributeProperties::ItemChange( nWhich
, pNewItem
);
125 TextProperties::ItemChange( nWhich
, pNewItem
);
128 // create a new itemset
129 std::unique_ptr
<SfxItemSet
> TableProperties::CreateObjectSpecificItemSet(SfxItemPool
& rPool
)
131 return std::make_unique
<SfxItemSet
>(rPool
,
133 // range from SdrAttrObj
134 svl::Items
<SDRATTR_START
, SDRATTR_SHADOW_LAST
,
135 SDRATTR_MISC_FIRST
, SDRATTR_MISC_LAST
,
136 SDRATTR_TEXTDIRECTION
, SDRATTR_TEXTDIRECTION
,
138 // range for SdrTableObj
139 SDRATTR_TABLE_FIRST
, SDRATTR_TABLE_LAST
,
141 // range from SdrTextObj
142 EE_ITEMS_START
, EE_ITEMS_END
>{});
145 class TableObjectGeoData
: public SdrTextObjGeoData
148 tools::Rectangle maLogicRect
;
151 TableStyleSettings::TableStyleSettings()
152 : mbUseFirstRow(true)
153 , mbUseLastRow(false)
154 , mbUseFirstColumn(false)
155 , mbUseLastColumn(false)
156 , mbUseRowBanding(true)
157 , mbUseColumnBanding(false)
161 TableStyleSettings::TableStyleSettings( const TableStyleSettings
& rStyle
)
166 TableStyleSettings
& TableStyleSettings::operator=(const TableStyleSettings
& rStyle
)
168 mbUseFirstRow
= rStyle
.mbUseFirstRow
;
169 mbUseLastRow
= rStyle
.mbUseLastRow
;
170 mbUseFirstColumn
= rStyle
.mbUseFirstColumn
;
171 mbUseLastColumn
= rStyle
.mbUseLastColumn
;
172 mbUseRowBanding
= rStyle
.mbUseRowBanding
;
173 mbUseColumnBanding
= rStyle
.mbUseColumnBanding
;
177 bool TableStyleSettings::operator==( const TableStyleSettings
& rStyle
) const
180 (mbUseFirstRow
== rStyle
.mbUseFirstRow
) &&
181 (mbUseLastRow
== rStyle
.mbUseLastRow
) &&
182 (mbUseFirstColumn
== rStyle
.mbUseFirstColumn
) &&
183 (mbUseLastColumn
== rStyle
.mbUseLastColumn
) &&
184 (mbUseRowBanding
== rStyle
.mbUseRowBanding
) &&
185 (mbUseColumnBanding
== rStyle
.mbUseColumnBanding
);
189 class SdrTableObjImpl
: public TableDesignUser
, public ::cppu::WeakImplHelper
< css::util::XModifyListener
>
192 CellRef mxActiveCell
;
193 TableModelRef mxTable
;
194 SdrTableObj
* mpTableObj
;
195 std::unique_ptr
<TableLayouter
> mpLayouter
;
197 TableStyleSettings maTableStyle
;
198 Reference
< XIndexAccess
> mxTableStyle
;
199 std::vector
<std::unique_ptr
<SdrUndoAction
>> maUndos
;
200 bool mbSkipChangeLayout
;
202 void CropTableModelToSelection(const CellPos
& rStart
, const CellPos
& rEnd
);
204 CellRef
getCell( const CellPos
& rPos
) const;
205 void LayoutTable( tools::Rectangle
& rArea
, bool bFitWidth
, bool bFitHeight
);
207 void ApplyCellStyles();
208 void UpdateCells( tools::Rectangle
const & rArea
);
211 virtual ~SdrTableObjImpl() override
;
213 void init( SdrTableObj
* pTable
, sal_Int32 nColumns
, sal_Int32 nRows
);
216 sal_Int32
getColumnCount() const;
217 /// Get widths of the columns in the table.
218 std::vector
<sal_Int32
> getColumnWidths() const;
219 sal_Int32
getRowCount() const;
221 void DragEdge( bool mbHorizontal
, int nEdge
, sal_Int32 nOffset
);
223 SdrTableObjImpl
& operator=( const SdrTableObjImpl
& rSource
);
226 virtual void SAL_CALL
modified( const css::lang::EventObject
& aEvent
) override
;
229 virtual void SAL_CALL
disposing( const css::lang::EventObject
& Source
) override
;
233 void connectTableStyle();
234 void disconnectTableStyle();
235 virtual bool isInUse() override
;
236 void dumpAsXml(xmlTextWriterPtr pWriter
) const;
238 static SdrTableObjImpl
* lastLayoutTable
;
239 static tools::Rectangle lastLayoutInputRectangle
;
240 static tools::Rectangle lastLayoutResultRectangle
;
241 static bool lastLayoutFitWidth
;
242 static bool lastLayoutFitHeight
;
243 static WritingMode lastLayoutMode
;
244 static sal_Int32 lastRowCount
;
245 static sal_Int32 lastColCount
;
246 static std::vector
<sal_Int32
> lastColWidths
;
249 SdrTableObjImpl
* SdrTableObjImpl::lastLayoutTable
= nullptr;
250 tools::Rectangle
SdrTableObjImpl::lastLayoutInputRectangle
;
251 tools::Rectangle
SdrTableObjImpl::lastLayoutResultRectangle
;
252 bool SdrTableObjImpl::lastLayoutFitWidth
;
253 bool SdrTableObjImpl::lastLayoutFitHeight
;
254 WritingMode
SdrTableObjImpl::lastLayoutMode
;
255 sal_Int32
SdrTableObjImpl::lastRowCount
;
256 sal_Int32
SdrTableObjImpl::lastColCount
;
257 std::vector
<sal_Int32
> SdrTableObjImpl::lastColWidths
;
259 SdrTableObjImpl::SdrTableObjImpl()
260 : mpTableObj( nullptr )
261 , mbSkipChangeLayout(false)
266 SdrTableObjImpl::~SdrTableObjImpl()
268 if( lastLayoutTable
== this )
269 lastLayoutTable
= nullptr;
273 void SdrTableObjImpl::CropTableModelToSelection(const CellPos
& rStart
, const CellPos
& rEnd
)
280 const sal_Int32
nColumns(rEnd
.mnCol
- rStart
.mnCol
+ 1);
281 const sal_Int32
nRows(rEnd
.mnRow
- rStart
.mnRow
+ 1);
283 if(nColumns
< 1 || nRows
< 1 || nColumns
> getColumnCount() || nRows
> getRowCount())
288 // tdf#116977 First thought was to create the new TableModel, copy data to it and then exchange
289 // mxTable and dispose old one. This does *not* work, even when all stuff looks nicely referenced
290 // and safe *because* Cell::create gets handed over the current SdrTableObj, hands it to
291 // ::Cell and there the local mxTable is initialized using rTableObj.getTable() (!). Due to This,
292 // the new created Cells in a new created TableModel based on given mpTableObj *will be disposed*
293 // when the old mxTable gets disposed - ARGH!
294 // To avoid, change strategy: Remember old TableModel, reset mxTable immediately - this is the
295 // SdrTableObjImpl of the current SdrTableObj anyways. Luckily, this works as intended...
297 // remember old TableModel
298 TableModelRef
xOldTable(mxTable
);
300 // immediately create new one and initialize. This creates ::Cell's which then will use
301 // the correct TableModel (accessed through SdrTableObj, but using local mxTable)
302 mxTable
= new TableModel(mpTableObj
);
303 mxTable
->init(nColumns
, nRows
);
306 for( sal_Int32 nRow
= 0; nRow
< nRows
; ++nRow
)
308 for( sal_Int32 nCol
= 0; nCol
< nColumns
; ++nCol
) try
310 CellRef
xTargetCell( dynamic_cast< Cell
* >( mxTable
->getCellByPosition( nCol
, nRow
).get() ) );
311 if( xTargetCell
.is() )
312 xTargetCell
->cloneFrom( dynamic_cast< Cell
* >( xOldTable
->getCellByPosition( rStart
.mnCol
+ nCol
, rStart
.mnRow
+ nRow
).get() ) );
316 OSL_FAIL( "SdrTableObj::CropTableModelToSelection(), exception caught!" );
321 Reference
< XTableRows
> xNewRows(mxTable
->getRows(), css::uno::UNO_SET_THROW
);
322 const OUString
sHeight( "Height" );
323 for( sal_Int32 nRow
= 0; nRow
< nRows
; ++nRow
)
325 Reference
< XPropertySet
> xNewSet( xNewRows
->getByIndex( nRow
), UNO_QUERY_THROW
);
326 xNewSet
->setPropertyValue( sHeight
, Any( mpLayouter
->getRowHeight( rStart
.mnRow
+ nRow
) ) );
329 // copy column widths
330 Reference
< XTableColumns
> xNewColumns( mxTable
->getColumns(), css::uno::UNO_SET_THROW
);
331 const OUString
sWidth( "Width" );
332 for( sal_Int32 nCol
= 0; nCol
< nColumns
; ++nCol
)
334 Reference
< XPropertySet
> xNewSet( xNewColumns
->getByIndex( nCol
), UNO_QUERY_THROW
);
335 xNewSet
->setPropertyValue( sWidth
, Any( mpLayouter
->getColumnWidth( rStart
.mnCol
+ nCol
) ) );
338 // reset layouter which still holds a copy to old TableModel
341 // cleanup old TableModel
343 Reference
< XModifyListener
> xListener( static_cast< css::util::XModifyListener
* >(this) );
344 xOldTable
->removeModifyListener( xListener
);
345 xOldTable
->dispose();
349 // create and hand over to new TableLayouter
350 mpLayouter
.reset(new TableLayouter( mxTable
));
352 // add needed listener to react on changes
353 Reference
< XModifyListener
> xListener( static_cast< css::util::XModifyListener
* >(this) );
354 mxTable
->addModifyListener( xListener
);
356 // Apply Style to Cells
359 // layout cropped table
360 LayoutTable( mpTableObj
->maRect
, false, false );
363 void SdrTableObjImpl::init( SdrTableObj
* pTable
, sal_Int32 nColumns
, sal_Int32 nRows
)
366 mxTable
= new TableModel( pTable
);
367 mxTable
->init( nColumns
, nRows
);
368 Reference
< XModifyListener
> xListener( static_cast< css::util::XModifyListener
* >(this) );
369 mxTable
->addModifyListener( xListener
);
370 mpLayouter
.reset(new TableLayouter( mxTable
));
371 LayoutTable( mpTableObj
->maRect
, true, true );
372 mpTableObj
->maLogicRect
= mpTableObj
->maRect
;
376 SdrTableObjImpl
& SdrTableObjImpl::operator=( const SdrTableObjImpl
& rSource
)
383 if(nullptr == mpTableObj
|| nullptr == rSource
.mpTableObj
)
385 // error: need both SdrObjects to successfully copy data
389 // remove evtl. listeners from local
390 disconnectTableStyle();
392 // reset layouter which holds a copy
395 // cleanup local mxTable if used
398 Reference
< XModifyListener
> xListener( static_cast< css::util::XModifyListener
* >(this) );
399 mxTable
->removeModifyListener( xListener
);
404 // tdf#127481: reset active cell reference
405 mxActiveCell
.clear();
407 // copy TableStyle (short internal data)
408 maTableStyle
= rSource
.maTableStyle
;
410 // create/copy new mxTable. This will copy all needed cells, too
411 mxTable
= new TableModel( mpTableObj
, rSource
.mxTable
);
413 // create and hand over to new TableLayouter
414 mpLayouter
.reset(new TableLayouter( mxTable
));
416 // add needed listener to react on changes
417 Reference
< XModifyListener
> xListener( static_cast< css::util::XModifyListener
* >(this) );
418 mxTable
->addModifyListener( xListener
);
421 Reference
< XIndexAccess
> xNewTableStyle
;
422 SdrModel
& rSourceSdrModel(rSource
.mpTableObj
->getSdrModelFromSdrObject());
423 SdrModel
& rTargetSdrModel(mpTableObj
->getSdrModelFromSdrObject());
425 if(rSource
.mxTableStyle
.is() && &rSourceSdrModel
== &rTargetSdrModel
)
427 // source and target model the same -> keep current TableStyle
428 xNewTableStyle
= rSource
.mxTableStyle
;
431 if(!xNewTableStyle
.is() && rSource
.mxTableStyle
.is()) try
433 // search in traget SdrModel for that TableStyle
434 const OUString
sStyleName( Reference
< XNamed
>( rSource
.mxTableStyle
, UNO_QUERY_THROW
)->getName() );
435 Reference
< XStyleFamiliesSupplier
> xSFS(rTargetSdrModel
.getUnoModel(), UNO_QUERY_THROW
);
436 Reference
< XNameAccess
> xFamilyNameAccess( xSFS
->getStyleFamilies(), css::uno::UNO_SET_THROW
);
437 const OUString
sFamilyName( "table" );
438 Reference
< XNameAccess
> xTableFamilyAccess( xFamilyNameAccess
->getByName( sFamilyName
), UNO_QUERY_THROW
);
440 if( xTableFamilyAccess
->hasByName( sStyleName
) )
442 // found table style with the same name
443 xTableFamilyAccess
->getByName( sStyleName
) >>= xNewTableStyle
;
447 // copy or? Not found, use 1st existing TableStyle (or none)
448 Reference
< XIndexAccess
> xIndexAccess( xTableFamilyAccess
, UNO_QUERY_THROW
);
449 xIndexAccess
->getByIndex( 0 ) >>= xNewTableStyle
;
454 OSL_FAIL("svx::SdrTableObjImpl::operator=(), exception caught!");
457 // set that TableStyle
458 mxTableStyle
= xNewTableStyle
;
460 // Apply Style to Cells
464 mpTableObj
->maRect
= mpTableObj
->maLogicRect
;
466 // layout cloned table
467 LayoutTable( mpTableObj
->maRect
, false, false );
469 // re-connect to styles (evtl. in new SdrModel)
475 void SdrTableObjImpl::ApplyCellStyles()
477 if( !mxTable
.is() || !mxTableStyle
.is() )
480 const sal_Int32 nColCount
= getColumnCount();
481 const sal_Int32 nRowCount
= getRowCount();
483 const TableStyleSettings
& rStyle
= maTableStyle
;
486 for( aPos
.mnRow
= 0; aPos
.mnRow
< nRowCount
; ++aPos
.mnRow
)
488 const bool bFirstRow
= (aPos
.mnRow
== 0) && rStyle
.mbUseFirstRow
;
489 const bool bLastRow
= (aPos
.mnRow
== nRowCount
-1) && rStyle
.mbUseLastRow
;
491 for( aPos
.mnCol
= 0; aPos
.mnCol
< nColCount
; ++aPos
.mnCol
)
493 Reference
< XStyle
> xStyle
;
495 // first and last row win first, if used and available
498 mxTableStyle
->getByIndex(first_row_style
) >>= xStyle
;
502 mxTableStyle
->getByIndex(last_row_style
) >>= xStyle
;
507 // next come first and last column, if used and available
508 if( rStyle
.mbUseFirstColumn
&& (aPos
.mnCol
== 0) )
510 mxTableStyle
->getByIndex(first_column_style
) >>= xStyle
;
512 else if( rStyle
.mbUseLastColumn
&& (aPos
.mnCol
== nColCount
-1) )
514 mxTableStyle
->getByIndex(last_column_style
) >>= xStyle
;
518 if( !xStyle
.is() && rStyle
.mbUseRowBanding
)
520 if( (aPos
.mnRow
& 1) == 0 )
522 mxTableStyle
->getByIndex(even_rows_style
) >>= xStyle
;
526 mxTableStyle
->getByIndex(odd_rows_style
) >>= xStyle
;
530 if( !xStyle
.is() && rStyle
.mbUseColumnBanding
)
532 if( (aPos
.mnCol
& 1) == 0 )
534 mxTableStyle
->getByIndex(even_columns_style
) >>= xStyle
;
538 mxTableStyle
->getByIndex(odd_columns_style
) >>= xStyle
;
544 // use default cell style if non found yet
545 mxTableStyle
->getByIndex(body_style
) >>= xStyle
;
551 SfxUnoStyleSheet
* pStyle
= SfxUnoStyleSheet::getUnoStyleSheet(xStyle
);
555 CellRef
xCell( getCell( aPos
) );
556 if( xCell
.is() && ( xCell
->GetStyleSheet() != pStyle
) )
558 xCell
->SetStyleSheet( pStyle
, true );
567 void SdrTableObjImpl::dispose()
569 disconnectTableStyle();
570 mxTableStyle
.clear();
576 Reference
< XModifyListener
> xListener( static_cast< css::util::XModifyListener
* >(this) );
577 mxTable
->removeModifyListener( xListener
);
584 void SdrTableObjImpl::DragEdge( bool mbHorizontal
, int nEdge
, sal_Int32 nOffset
)
586 if( (nEdge
>= 0) && mxTable
.is()) try
588 const OUString
sSize( "Size" );
591 if (nEdge
<= getRowCount())
593 sal_Int32 nHeight
= mpLayouter
->getRowHeight( (!nEdge
)?nEdge
:(nEdge
-1) );
598 Reference
< XIndexAccess
> xRows( mxTable
->getRows(), UNO_QUERY_THROW
);
599 Reference
< XPropertySet
> xRowSet( xRows
->getByIndex( (!nEdge
)?nEdge
:(nEdge
-1) ), UNO_QUERY_THROW
);
600 xRowSet
->setPropertyValue( sSize
, Any( nHeight
) );
606 fixes fdo#59889 and resizing of table in edge dragging
607 Total vertical edges in a NxN table is N+1, indexed from 0 to N and total Columns is N, indexed from 0 to N-1
608 In LTR table vertical edge responsible for dragging of column x(x=0 to N-1) is, Edge x+1
609 But in RTL table vertical edge responsible for dragging of column x(x=0 to N-1, but from right to left)is, Edge x
610 In LTR table dragging of edge 0(for RTL table edge N) does nothing.
612 //Todo: Implement Dragging functionality for leftmost edge of table.
613 if (nEdge
<= getColumnCount())
615 const bool bRTL
= mpTableObj
!= nullptr && (mpTableObj
->GetWritingMode() == WritingMode_RL_TB
);
619 nWidth
= mpLayouter
->getColumnWidth( nEdge
);
623 nWidth
= mpLayouter
->getColumnWidth( (!nEdge
)?nEdge
:(nEdge
-1) );
625 Reference
< XIndexAccess
> xCols( mxTable
->getColumns(), UNO_QUERY_THROW
);
627 if(bRTL
&& nEdge
<getColumnCount())
629 Reference
< XPropertySet
> xColSet( xCols
->getByIndex( nEdge
), UNO_QUERY_THROW
);
630 xColSet
->setPropertyValue( sSize
, Any( nWidth
) );
632 else if(!bRTL
&& nEdge
>0)
634 Reference
< XPropertySet
> xColSet( xCols
->getByIndex( nEdge
-1 ), UNO_QUERY_THROW
);
635 xColSet
->setPropertyValue( sSize
, Any( nWidth
) );
637 /* To prevent the table resizing on edge dragging */
638 if( nEdge
> 0 && nEdge
< mxTable
->getColumnCount() )
643 nWidth
= mpLayouter
->getColumnWidth(nEdge
);
644 nWidth
= std::max(static_cast<sal_Int32
>(nWidth
- nOffset
), sal_Int32(0));
646 Reference
<XPropertySet
> xColSet(xCols
->getByIndex(nEdge
), UNO_QUERY_THROW
);
647 xColSet
->setPropertyValue(sSize
, Any(nWidth
));
654 OSL_FAIL( "svx::SdrTableObjImpl::DragEdge(), exception caught!" );
662 void SAL_CALL
SdrTableObjImpl::modified( const css::lang::EventObject
& /*aEvent*/ )
667 void SdrTableObjImpl::update()
669 // source can be the table model itself or the assigned table template
670 TableModelNotifyGuard
aGuard( mxTable
.get() );
673 if( (maEditPos
.mnRow
>= getRowCount()) || (maEditPos
.mnCol
>= getColumnCount()) || (getCell( maEditPos
) != mxActiveCell
) )
675 if(maEditPos
.mnRow
>= getRowCount())
676 maEditPos
.mnRow
= getRowCount()-1;
678 if(maEditPos
.mnCol
>= getColumnCount())
679 maEditPos
.mnCol
= getColumnCount()-1;
681 mpTableObj
->setActiveCell( maEditPos
);
686 mpTableObj
->maRect
= mpTableObj
->maLogicRect
;
687 LayoutTable( mpTableObj
->maRect
, false, false );
689 mpTableObj
->SetRectsDirty();
690 mpTableObj
->ActionChanged();
691 mpTableObj
->BroadcastObjectChange();
696 void SdrTableObjImpl::connectTableStyle()
698 if( mxTableStyle
.is() )
700 Reference
< XModifyBroadcaster
> xBroadcaster( mxTableStyle
, UNO_QUERY
);
701 if( xBroadcaster
.is() )
703 Reference
< XModifyListener
> xListener( static_cast< css::util::XModifyListener
* >(this) );
704 xBroadcaster
->addModifyListener( xListener
);
710 void SdrTableObjImpl::disconnectTableStyle()
712 if( mxTableStyle
.is() )
714 Reference
< XModifyBroadcaster
> xBroadcaster( mxTableStyle
, UNO_QUERY
);
715 if( xBroadcaster
.is() )
717 Reference
< XModifyListener
> xListener( static_cast< css::util::XModifyListener
* >(this) );
718 xBroadcaster
->removeModifyListener( xListener
);
724 bool SdrTableObjImpl::isInUse()
726 return mpTableObj
&& mpTableObj
->IsInserted();
729 void SdrTableObjImpl::dumpAsXml(xmlTextWriterPtr pWriter
) const
731 xmlTextWriterStartElement(pWriter
, BAD_CAST("SdrTableObjImpl"));
733 mpLayouter
->dumpAsXml(pWriter
);
734 mxTable
->dumpAsXml(pWriter
);
735 xmlTextWriterEndElement(pWriter
);
742 void SAL_CALL
SdrTableObjImpl::disposing( const css::lang::EventObject
& /*Source*/ )
744 mxActiveCell
.clear();
747 mpTableObj
= nullptr;
751 CellRef
SdrTableObjImpl::getCell( const CellPos
& rPos
) const
754 if( mxTable
.is() ) try
756 xCell
.set( dynamic_cast< Cell
* >( mxTable
->getCellByPosition( rPos
.mnCol
, rPos
.mnRow
).get() ) );
760 OSL_FAIL( "svx::SdrTableObjImpl::getCell(), exception caught!" );
766 sal_Int32
SdrTableObjImpl::getColumnCount() const
768 return mxTable
.is() ? mxTable
->getColumnCount() : 0;
771 std::vector
<sal_Int32
> SdrTableObjImpl::getColumnWidths() const
773 std::vector
<sal_Int32
> aRet
;
776 aRet
= mxTable
->getColumnWidths();
781 sal_Int32
SdrTableObjImpl::getRowCount() const
783 return mxTable
.is() ? mxTable
->getRowCount() : 0;
786 void SdrTableObjImpl::LayoutTable( tools::Rectangle
& rArea
, bool bFitWidth
, bool bFitHeight
)
790 // Optimization: SdrTableObj::SetChanged() can call this very often, repeatedly
791 // with the same settings, noticeably increasing load time. Skip if already done.
792 bool bInteractiveMightGrowBecauseTextChanged
=
793 mpTableObj
->IsReallyEdited() && (mpTableObj
->IsAutoGrowHeight() || mpTableObj
->IsAutoGrowWidth());
794 WritingMode writingMode
= mpTableObj
->GetWritingMode();
795 if( bInteractiveMightGrowBecauseTextChanged
796 || lastLayoutTable
!= this || lastLayoutInputRectangle
!= rArea
797 || lastLayoutFitWidth
!= bFitWidth
|| lastLayoutFitHeight
!= bFitHeight
798 || lastLayoutMode
!= writingMode
799 || lastRowCount
!= getRowCount()
800 || lastColCount
!= getColumnCount()
801 || lastColWidths
!= getColumnWidths() )
803 lastLayoutTable
= this;
804 lastLayoutInputRectangle
= rArea
;
805 lastLayoutFitWidth
= bFitWidth
;
806 lastLayoutFitHeight
= bFitHeight
;
807 lastLayoutMode
= writingMode
;
808 lastRowCount
= getRowCount();
809 lastColCount
= getColumnCount();
810 // Column resize, when the total width and column count of the
811 // table is unchanged, but re-layout is still needed.
812 lastColWidths
= getColumnWidths();
813 TableModelNotifyGuard
aGuard( mxTable
.get() );
814 mpLayouter
->LayoutTable( rArea
, bFitWidth
, bFitHeight
);
815 lastLayoutResultRectangle
= rArea
;
819 rArea
= lastLayoutResultRectangle
;
820 mpLayouter
->UpdateBorderLayout();
825 void SdrTableObjImpl::UpdateCells( tools::Rectangle
const & rArea
)
827 if( mpLayouter
&& mxTable
.is() )
829 TableModelNotifyGuard
aGuard( mxTable
.get() );
830 mpLayouter
->updateCells( rArea
);
831 mxTable
->setModified(true);
836 // BaseProperties section
839 std::unique_ptr
<sdr::properties::BaseProperties
> SdrTableObj::CreateObjectSpecificProperties()
841 return std::make_unique
<TableProperties
>(*this);
845 // DrawContact section
848 std::unique_ptr
<sdr::contact::ViewContact
> SdrTableObj::CreateObjectSpecificViewContact()
850 return std::make_unique
<sdr::contact::ViewContactOfTableObj
>(*this);
853 SdrTableObj::SdrTableObj(SdrModel
& rSdrModel
)
854 : SdrTextObj(rSdrModel
)
859 SdrTableObj::SdrTableObj(
861 const ::tools::Rectangle
& rNewRect
,
864 : SdrTextObj(rSdrModel
, rNewRect
)
865 ,maLogicRect(rNewRect
)
873 init( nColumns
, nRows
);
877 void SdrTableObj::init( sal_Int32 nColumns
, sal_Int32 nRows
)
881 mpImpl
= new SdrTableObjImpl
;
882 mpImpl
->init( this, nColumns
, nRows
);
884 // Stuff done from old SetModel:
885 if( !maLogicRect
.IsEmpty() )
887 maRect
= maLogicRect
;
888 mpImpl
->LayoutTable( maRect
, false, false );
893 SdrTableObj::~SdrTableObj()
902 Reference
< XTable
> SdrTableObj::getTable() const
904 return Reference
< XTable
>( mpImpl
->mxTable
.get() );
908 bool SdrTableObj::isValid( const CellPos
& rPos
) const
910 return (rPos
.mnCol
>= 0) && (rPos
.mnCol
< mpImpl
->getColumnCount()) && (rPos
.mnRow
>= 0) && (rPos
.mnRow
< mpImpl
->getRowCount());
914 CellPos
SdrTableObj::getFirstCell()
916 return CellPos( 0,0 );
920 CellPos
SdrTableObj::getLastCell() const
923 if( mpImpl
->mxTable
.is() )
925 aPos
.mnCol
= mpImpl
->getColumnCount()-1;
926 aPos
.mnRow
= mpImpl
->getRowCount()-1;
932 CellPos
SdrTableObj::getLeftCell( const CellPos
& rPos
, bool bEdgeTravel
) const
934 switch( GetWritingMode() )
937 case WritingMode_LR_TB
:
938 return getPreviousCell( rPos
, bEdgeTravel
);
939 case WritingMode_RL_TB
:
940 return getNextCell( rPos
, bEdgeTravel
);
941 case WritingMode_TB_RL
:
942 return getPreviousRow( rPos
, bEdgeTravel
);
947 CellPos
SdrTableObj::getRightCell( const CellPos
& rPos
, bool bEdgeTravel
) const
949 switch( GetWritingMode() )
952 case WritingMode_LR_TB
:
953 return getNextCell( rPos
, bEdgeTravel
);
954 case WritingMode_RL_TB
:
955 return getPreviousCell( rPos
, bEdgeTravel
);
956 case WritingMode_TB_RL
:
957 return getNextRow( rPos
, bEdgeTravel
);
962 CellPos
SdrTableObj::getUpCell( const CellPos
& rPos
, bool bEdgeTravel
) const
964 switch( GetWritingMode() )
967 case WritingMode_LR_TB
:
968 case WritingMode_RL_TB
:
969 return getPreviousRow( rPos
, bEdgeTravel
);
970 case WritingMode_TB_RL
:
971 return getPreviousCell( rPos
, bEdgeTravel
);
976 CellPos
SdrTableObj::getDownCell( const CellPos
& rPos
, bool bEdgeTravel
) const
978 switch( GetWritingMode() )
981 case WritingMode_LR_TB
:
982 case WritingMode_RL_TB
:
983 return getNextRow( rPos
, bEdgeTravel
);
984 case WritingMode_TB_RL
:
985 return getNextCell( rPos
, bEdgeTravel
);
990 CellPos
SdrTableObj::getPreviousCell( const CellPos
& rPos
, bool bEdgeTravel
) const
992 CellPos
aPos( rPos
);
995 CellRef
xCell( mpImpl
->getCell( aPos
) );
996 if( xCell
.is() && xCell
->isMerged() )
999 findMergeOrigin( mpImpl
->mxTable
.get(), aPos
.mnCol
, aPos
.mnRow
, aPos
.mnCol
, nTemp
);
1002 if( aPos
.mnCol
> 0 )
1007 else if( bEdgeTravel
&& (aPos
.mnRow
> 0) )
1009 aPos
.mnCol
= mpImpl
->mxTable
->getColumnCount()-1;
1017 CellPos
SdrTableObj::getNextCell( const CellPos
& rPos
, bool bEdgeTravel
) const
1019 CellPos
aPos( rPos
);
1022 CellRef
xCell( mpImpl
->getCell( aPos
) );
1025 if( xCell
->isMerged() )
1027 findMergeOrigin( mpImpl
->mxTable
, aPos
.mnCol
, aPos
.mnRow
, aPos
.mnCol
, aPos
.mnRow
);
1029 xCell
= mpImpl
->getCell(aPos
);
1033 aPos
.mnCol
+= xCell
->getColumnSpan();
1034 aPos
.mnRow
= rPos
.mnRow
;
1039 aPos
.mnCol
+= xCell
->getColumnSpan();
1042 if( aPos
.mnCol
< mpImpl
->mxTable
->getColumnCount() )
1045 if( bEdgeTravel
&& ((aPos
.mnRow
+ 1) < mpImpl
->getRowCount()) )
1054 // last cell reached, no traveling possible
1059 CellPos
SdrTableObj::getPreviousRow( const CellPos
& rPos
, bool bEdgeTravel
) const
1061 CellPos
aPos( rPos
);
1064 CellRef
xCell( mpImpl
->getCell( aPos
) );
1065 if( xCell
.is() && xCell
->isMerged() )
1067 sal_Int32 nTemp
= 0;
1068 findMergeOrigin( mpImpl
->mxTable
, aPos
.mnCol
, aPos
.mnRow
, nTemp
, aPos
.mnRow
);
1071 if( aPos
.mnRow
> 0 )
1075 else if( bEdgeTravel
&& (aPos
.mnCol
> 0) )
1077 aPos
.mnRow
= mpImpl
->mxTable
->getRowCount()-1;
1085 CellPos
SdrTableObj::getNextRow( const CellPos
& rPos
, bool bEdgeTravel
) const
1087 CellPos
aPos( rPos
);
1091 CellRef
xCell( mpImpl
->getCell( rPos
) );
1094 if( xCell
->isMerged() )
1096 findMergeOrigin( mpImpl
->mxTable
, aPos
.mnCol
, aPos
.mnRow
, aPos
.mnCol
, aPos
.mnRow
);
1097 xCell
= mpImpl
->getCell(aPos
);
1098 aPos
.mnCol
= rPos
.mnCol
;
1102 aPos
.mnRow
+= xCell
->getRowSpan();
1104 if( aPos
.mnRow
< mpImpl
->mxTable
->getRowCount() )
1107 if( bEdgeTravel
&& (aPos
.mnCol
+ 1) < mpImpl
->mxTable
->getColumnCount() )
1112 while( aPos
.mnCol
< mpImpl
->mxTable
->getColumnCount() )
1114 xCell
= mpImpl
->getCell( aPos
);
1115 if( xCell
.is() && !xCell
->isMerged() )
1123 // last position reached, no more traveling possible
1128 const TableStyleSettings
& SdrTableObj::getTableStyleSettings() const
1132 return mpImpl
->maTableStyle
;
1136 static TableStyleSettings aTmp
;
1142 void SdrTableObj::setTableStyleSettings( const TableStyleSettings
& rStyle
)
1146 mpImpl
->maTableStyle
= rStyle
;
1152 TableHitKind
SdrTableObj::CheckTableHit( const Point
& rPos
, sal_Int32
& rnX
, sal_Int32
& rnY
, const sal_uInt16 aTol
) const
1154 if( !mpImpl
.is() || !mpImpl
->mxTable
.is() )
1155 return TableHitKind::NONE
;
1160 const sal_Int32 nColCount
= mpImpl
->getColumnCount();
1161 const sal_Int32 nRowCount
= mpImpl
->getRowCount();
1163 sal_Int32 nX
= rPos
.X() - maRect
.Left();
1164 sal_Int32 nY
= rPos
.Y() - maRect
.Top();
1166 if( (nX
< 0) || (nX
> maRect
.GetWidth()) || (nY
< 0) || (nY
> maRect
.GetHeight() ) )
1167 return TableHitKind::NONE
;
1169 // get vertical edge number and check for a hit
1170 const bool bRTL
= (GetWritingMode() == WritingMode_RL_TB
);
1171 bool bVrtHit
= false;
1174 while( rnX
<= nColCount
)
1176 if( nX
- aTol
<= 0 )
1182 if( rnX
== nColCount
)
1185 nX
-= mpImpl
->mpLayouter
->getColumnWidth( rnX
);
1196 if( nX
- aTol
<= 0 )
1206 nX
-= mpImpl
->mpLayouter
->getColumnWidth( rnX
);
1212 // rnX is now the edge number left to the pointer, if it was hit bHrzHit is also true
1214 // get vertical edge number and check for a hit
1215 bool bHrzHit
= false;
1216 while( rnY
<= nRowCount
)
1218 if( nY
- aTol
<= 0 )
1224 if( rnY
== nRowCount
)
1227 nY
-= mpImpl
->mpLayouter
->getRowHeight(rnY
);
1233 // rnY is now the edge number above the pointer, if it was hit bVrtHit is also true
1235 if( bVrtHit
&& mpImpl
->mpLayouter
->isEdgeVisible( rnX
, rnY
, false ) )
1236 return TableHitKind::VerticallBorder
;
1238 if( bHrzHit
&& mpImpl
->mpLayouter
->isEdgeVisible( rnX
, rnY
, true ) )
1239 return TableHitKind::HorizontalBorder
;
1241 CellRef
xCell( mpImpl
->getCell( CellPos( rnX
, rnY
) ) );
1242 if( xCell
.is() && xCell
->isMerged() )
1243 findMergeOrigin( mpImpl
->mxTable
.get(), rnX
, rnY
, rnX
, rnY
);
1247 nX
+= mpImpl
->mpLayouter
->getColumnWidth( rnX
);
1248 //Fix for fdo#62673 : non-editable cell in table on cell merge
1250 while(xCell
.is() && xCell
->isMerged())
1252 nX
+= mpImpl
->mpLayouter
->getColumnWidth( rnX
+i
);
1254 if(rnX
+i
< nColCount
)
1255 xCell
=mpImpl
->getCell( CellPos( rnX
+i
, rnY
) );
1260 if( nX
< xCell
->GetTextLeftDistance() )
1261 return TableHitKind::Cell
;
1264 return TableHitKind::CellTextArea
;
1267 const SfxItemSet
& SdrTableObj::GetActiveCellItemSet() const
1269 return getActiveCell()->GetItemSet();
1272 void SdrTableObj::setTableStyle( const Reference
< XIndexAccess
>& xTableStyle
)
1274 if( mpImpl
.is() && (mpImpl
->mxTableStyle
!= xTableStyle
) )
1276 mpImpl
->disconnectTableStyle();
1277 mpImpl
->mxTableStyle
= xTableStyle
;
1278 mpImpl
->connectTableStyle();
1284 const Reference
< XIndexAccess
>& SdrTableObj::getTableStyle() const
1288 return mpImpl
->mxTableStyle
;
1292 static Reference
< XIndexAccess
> aTmp
;
1301 /** returns the currently active text. */
1302 SdrText
* SdrTableObj::getActiveText() const
1304 return dynamic_cast< SdrText
* >( getActiveCell().get() );
1308 /** returns the nth available text. */
1309 SdrText
* SdrTableObj::getText( sal_Int32 nIndex
) const
1311 if( mpImpl
->mxTable
.is() )
1313 const sal_Int32 nColCount
= mpImpl
->getColumnCount();
1316 CellPos
aPos( nIndex
% nColCount
, nIndex
/ nColCount
);
1318 CellRef
xCell( mpImpl
->getCell( aPos
) );
1319 return dynamic_cast< SdrText
* >( xCell
.get() );
1326 /** returns the number of texts available for this object. */
1327 sal_Int32
SdrTableObj::getTextCount() const
1329 if( mpImpl
->mxTable
.is() )
1331 const sal_Int32 nColCount
= mpImpl
->getColumnCount();
1332 const sal_Int32 nRowCount
= mpImpl
->getRowCount();
1334 return nColCount
* nRowCount
;
1343 /** changes the current active text */
1344 void SdrTableObj::setActiveText( sal_Int32 nIndex
)
1346 if( mpImpl
.is() && mpImpl
->mxTable
.is() )
1348 const sal_Int32 nColCount
= mpImpl
->mxTable
->getColumnCount();
1351 CellPos
aPos( nIndex
% nColCount
, nIndex
/ nColCount
);
1352 if( isValid( aPos
) )
1353 setActiveCell( aPos
);
1359 /** returns the index of the text that contains the given point or -1 */
1360 sal_Int32
SdrTableObj::CheckTextHit(const Point
& rPnt
) const
1362 if( mpImpl
.is() && mpImpl
->mxTable
.is() )
1365 if( CheckTableHit( rPnt
, aPos
.mnCol
, aPos
.mnRow
) == TableHitKind::CellTextArea
)
1366 return aPos
.mnRow
* mpImpl
->mxTable
->getColumnCount() + aPos
.mnCol
;
1372 SdrOutliner
* SdrTableObj::GetCellTextEditOutliner( const Cell
& rCell
) const
1374 if( mpImpl
.is() && (mpImpl
->getCell( mpImpl
->maEditPos
).get() == &rCell
) )
1380 const TableLayouter
& SdrTableObj::getTableLayouter() const
1382 assert(mpImpl
.is() && mpImpl
->mpLayouter
&& "getTableLayouter() error: no mpImpl or mpLayouter (!)");
1383 return *(mpImpl
->mpLayouter
);
1386 bool SdrTableObj::IsAutoGrowHeight() const
1391 bool SdrTableObj::IsAutoGrowWidth() const
1396 bool SdrTableObj::HasText() const
1401 bool SdrTableObj::IsTextEditActive( const CellPos
& rPos
)
1403 return pEdtOutl
&& mpImpl
.is() && (rPos
== mpImpl
->maEditPos
);
1407 void SdrTableObj::onEditOutlinerStatusEvent( EditStatus
* pEditStatus
)
1409 if( (pEditStatus
->GetStatusWord() & EditStatusFlags::TextHeightChanged
) && mpImpl
.is() && mpImpl
->mpLayouter
)
1411 tools::Rectangle
aRect0( maRect
);
1412 maRect
= maLogicRect
;
1413 mpImpl
->LayoutTable( maRect
, false, false );
1416 BroadcastObjectChange();
1417 if (aRect0
!= maRect
)
1418 SendUserCall(SdrUserCallType::Resize
,aRect0
);
1423 void SdrTableObj::TakeObjInfo(SdrObjTransformInfoRec
& rInfo
) const
1425 rInfo
.bResizeFreeAllowed
=true;
1426 rInfo
.bResizePropAllowed
=true;
1427 rInfo
.bRotateFreeAllowed
=false;
1428 rInfo
.bRotate90Allowed
=false;
1429 rInfo
.bMirrorFreeAllowed
=false;
1430 rInfo
.bMirror45Allowed
=false;
1431 rInfo
.bMirror90Allowed
=false;
1433 // allow transparence
1434 rInfo
.bTransparenceAllowed
= true;
1436 rInfo
.bShearAllowed
=false;
1437 rInfo
.bEdgeRadiusAllowed
=false;
1438 rInfo
.bCanConvToPath
=false;
1439 rInfo
.bCanConvToPoly
=false;
1440 rInfo
.bCanConvToPathLineToArea
=false;
1441 rInfo
.bCanConvToPolyLineToArea
=false;
1442 rInfo
.bCanConvToContour
= false;
1446 sal_uInt16
SdrTableObj::GetObjIdentifier() const
1448 return static_cast<sal_uInt16
>(OBJ_TABLE
);
1451 void SdrTableObj::TakeTextRect( SdrOutliner
& rOutliner
, tools::Rectangle
& rTextRect
, bool bNoEditText
, tools::Rectangle
* pAnchorRect
, bool /*bLineWidth*/ ) const
1454 TakeTextRect( mpImpl
->maEditPos
, rOutliner
, rTextRect
, bNoEditText
, pAnchorRect
);
1458 void SdrTableObj::TakeTextRect( const CellPos
& rPos
, SdrOutliner
& rOutliner
, tools::Rectangle
& rTextRect
, bool bNoEditText
, tools::Rectangle
* pAnchorRect
) const
1463 CellRef
xCell( mpImpl
->getCell( rPos
) );
1467 tools::Rectangle aAnkRect
;
1468 TakeTextAnchorRect( rPos
, aAnkRect
);
1470 SdrTextVertAdjust eVAdj
=xCell
->GetTextVerticalAdjust();
1472 EEControlBits nStat0
=rOutliner
.GetControlWord();
1473 nStat0
|= EEControlBits::AUTOPAGESIZE
;
1474 rOutliner
.SetControlWord(nStat0
);
1475 rOutliner
.SetMinAutoPaperSize(Size());
1476 rOutliner
.SetMaxAutoPaperSize(aAnkRect
.GetSize());
1477 rOutliner
.SetPaperSize(aAnkRect
.GetSize());
1479 // #103516# New try with _BLOCK for hor and ver after completely
1480 // supporting full width for vertical text.
1481 // if( SDRTEXTHORZADJUST_BLOCK == eHAdj && !IsVerticalWriting())
1483 rOutliner
.SetMinAutoPaperSize(Size(aAnkRect
.GetWidth(), 0));
1485 // else if(SDRTEXTVERTADJUST_BLOCK == eVAdj && IsVerticalWriting())
1487 // rOutliner.SetMinAutoPaperSize(Size(0, aAnkRect.GetHeight()));
1491 // set text at outliner, maybe from edit outliner
1492 OutlinerParaObject
* pPara
= xCell
->GetOutlinerParaObject();
1493 if (pEdtOutl
&& !bNoEditText
&& mpImpl
->mxActiveCell
== xCell
)
1494 pPara
=pEdtOutl
->CreateParaObject().release();
1498 const bool bHitTest(&getSdrModelFromSdrObject().GetHitTestOutliner() == &rOutliner
);
1499 const SdrTextObj
* pTestObj(rOutliner
.GetTextObj());
1501 if( !pTestObj
|| !bHitTest
|| (pTestObj
!= this) || (pTestObj
->GetOutlinerParaObject() != xCell
->GetOutlinerParaObject()) )
1503 if( bHitTest
) // #i33696# take back fix #i27510#
1504 rOutliner
.SetTextObj( this );
1506 rOutliner
.SetUpdateMode(true);
1507 rOutliner
.SetText(*pPara
);
1512 rOutliner
.SetTextObj( nullptr );
1515 if (pEdtOutl
&& !bNoEditText
&& pPara
&& mpImpl
->mxActiveCell
== xCell
)
1518 rOutliner
.SetUpdateMode(true);
1519 rOutliner
.SetControlWord(nStat0
);
1521 Point
aTextPos(aAnkRect
.TopLeft());
1522 Size
aTextSiz(rOutliner
.GetPaperSize());
1523 if (eVAdj
==SDRTEXTVERTADJUST_CENTER
|| eVAdj
==SDRTEXTVERTADJUST_BOTTOM
)
1525 long nFreeHgt
=aAnkRect
.GetHeight()-aTextSiz
.Height();
1526 if (eVAdj
==SDRTEXTVERTADJUST_CENTER
)
1527 aTextPos
.AdjustY(nFreeHgt
/2 );
1528 if (eVAdj
==SDRTEXTVERTADJUST_BOTTOM
)
1529 aTextPos
.AdjustY(nFreeHgt
);
1533 *pAnchorRect
=aAnkRect
;
1535 rTextRect
=tools::Rectangle(aTextPos
,aTextSiz
);
1539 const CellRef
& SdrTableObj::getActiveCell() const
1543 if( !mpImpl
->mxActiveCell
.is() )
1546 const_cast< SdrTableObj
* >(this)->setActiveCell( aPos
);
1548 return mpImpl
->mxActiveCell
;
1552 static CellRef xCell
;
1558 sal_Int32
SdrTableObj::getColumnCount() const
1560 return mpImpl
.is() ? mpImpl
->getColumnCount() : 0;
1563 sal_Int32
SdrTableObj::getRowCount() const
1565 return mpImpl
.is() ? mpImpl
->getRowCount() : 0;
1568 void SdrTableObj::changeEdge(bool bHorizontal
, int nEdge
, sal_Int32 nOffset
)
1571 mpImpl
->DragEdge(bHorizontal
, nEdge
, nOffset
);
1574 void SdrTableObj::setActiveCell( const CellPos
& rPos
)
1576 if( mpImpl
.is() && mpImpl
->mxTable
.is() ) try
1578 mpImpl
->mxActiveCell
.set( dynamic_cast< Cell
* >( mpImpl
->mxTable
->getCellByPosition( rPos
.mnCol
, rPos
.mnRow
).get() ) );
1579 if( mpImpl
->mxActiveCell
.is() && mpImpl
->mxActiveCell
->isMerged() )
1582 findMergeOrigin( mpImpl
->mxTable
.get(), rPos
.mnCol
, rPos
.mnRow
, aOrigin
.mnCol
, aOrigin
.mnRow
);
1583 mpImpl
->mxActiveCell
.set( dynamic_cast< Cell
* >( mpImpl
->mxTable
->getCellByPosition( aOrigin
.mnCol
, aOrigin
.mnRow
).get() ) );
1584 mpImpl
->maEditPos
= aOrigin
;
1588 mpImpl
->maEditPos
= rPos
;
1593 OSL_FAIL("SdrTableObj::setActiveCell(), exception caught!");
1598 void SdrTableObj::getActiveCellPos( CellPos
& rPos
) const
1600 rPos
= mpImpl
->maEditPos
;
1604 void SdrTableObj::getCellBounds( const CellPos
& rPos
, ::tools::Rectangle
& rCellRect
)
1608 CellRef
xCell( mpImpl
->getCell( rPos
) );
1610 rCellRect
= xCell
->getCellRect();
1615 void SdrTableObj::TakeTextAnchorRect(tools::Rectangle
& rAnchorRect
) const
1618 TakeTextAnchorRect( mpImpl
->maEditPos
, rAnchorRect
);
1622 void SdrTableObj::TakeTextAnchorRect( const CellPos
& rPos
, tools::Rectangle
& rAnchorRect
) const
1624 tools::Rectangle
aAnkRect(maRect
);
1628 CellRef
xCell( mpImpl
->getCell( rPos
) );
1630 xCell
->TakeTextAnchorRect( aAnkRect
);
1633 ImpJustifyRect(aAnkRect
);
1634 rAnchorRect
=aAnkRect
;
1638 void SdrTableObj::TakeTextEditArea(Size
* pPaperMin
, Size
* pPaperMax
, tools::Rectangle
* pViewInit
, tools::Rectangle
* pViewMin
) const
1641 TakeTextEditArea( mpImpl
->maEditPos
, pPaperMin
, pPaperMax
, pViewInit
, pViewMin
);
1645 void SdrTableObj::TakeTextEditArea( const CellPos
& rPos
, Size
* pPaperMin
, Size
* pPaperMax
, tools::Rectangle
* pViewInit
, tools::Rectangle
* pViewMin
) const
1647 Size aPaperMin
,aPaperMax
;
1648 tools::Rectangle aViewInit
;
1649 TakeTextAnchorRect( rPos
, aViewInit
);
1651 Size
aAnkSiz(aViewInit
.GetSize());
1652 aAnkSiz
.AdjustWidth( -1 ); aAnkSiz
.AdjustHeight( -1 ); // because GetSize() increments by one
1654 Size
aMaxSiz(aAnkSiz
.Width(),1000000);
1655 Size
aTmpSiz(getSdrModelFromSdrObject().GetMaxObjSize());
1656 if (aTmpSiz
.Height()!=0)
1657 aMaxSiz
.setHeight(aTmpSiz
.Height() );
1659 CellRef
xCell( mpImpl
->getCell( rPos
) );
1660 SdrTextVertAdjust eVAdj
= xCell
.is() ? xCell
->GetTextVerticalAdjust() : SDRTEXTVERTADJUST_TOP
;
1664 aPaperMin
.setWidth( aAnkSiz
.Width() );
1666 if (pViewMin
!=nullptr)
1668 *pViewMin
=aViewInit
;
1669 long nYFree
=aAnkSiz
.Height()-aPaperMin
.Height();
1671 if (eVAdj
==SDRTEXTVERTADJUST_TOP
)
1673 pViewMin
->AdjustBottom( -nYFree
);
1675 else if (eVAdj
==SDRTEXTVERTADJUST_BOTTOM
)
1677 pViewMin
->AdjustTop(nYFree
);
1681 pViewMin
->AdjustTop(nYFree
/2 );
1682 pViewMin
->SetBottom(pViewMin
->Top()+aPaperMin
.Height() );
1687 if(IsVerticalWriting())
1688 aPaperMin
.setWidth( 0 );
1690 aPaperMin
.setHeight( 0 );
1692 if (pPaperMin
!=nullptr) *pPaperMin
=aPaperMin
;
1693 if (pPaperMax
!=nullptr) *pPaperMax
=aPaperMax
;
1694 if (pViewInit
!=nullptr) *pViewInit
=aViewInit
;
1698 EEAnchorMode
SdrTableObj::GetOutlinerViewAnchorMode() const
1700 EEAnchorMode eRet
=EEAnchorMode::TopLeft
;
1701 CellRef
xCell( getActiveCell() );
1704 SdrTextVertAdjust eV
=xCell
->GetTextVerticalAdjust();
1707 if (eV
==SDRTEXTVERTADJUST_TOP
)
1709 eRet
=EEAnchorMode::TopLeft
;
1711 else if (eV
==SDRTEXTVERTADJUST_BOTTOM
)
1713 eRet
=EEAnchorMode::BottomLeft
;
1717 eRet
=EEAnchorMode::VCenterLeft
;
1725 OUString
SdrTableObj::TakeObjNameSingul() const
1727 OUStringBuffer
sName(SvxResId(STR_ObjNameSingulTable
));
1729 OUString
aName(GetName());
1730 if (!aName
.isEmpty())
1734 sName
.append(aName
);
1738 return sName
.makeStringAndClear();
1742 OUString
SdrTableObj::TakeObjNamePlural() const
1744 return SvxResId(STR_ObjNamePluralTable
);
1748 SdrTableObj
* SdrTableObj::CloneSdrObject(SdrModel
& rTargetModel
) const
1750 return CloneHelper
< SdrTableObj
>(rTargetModel
);
1753 SdrTableObj
& SdrTableObj::operator=(const SdrTableObj
& rObj
)
1761 // before SdrObject::operator= was called which is wrong from
1762 // the derivation hierarchy and may leave quite some entries
1763 // uninitialized. Changed to SdrTextObj::operator=, but had to adapt
1764 // usage of pNewOutlinerParaObject/mpText there due to nullptr access
1765 SdrTextObj::operator=(rObj
);
1767 TableModelNotifyGuard
aGuard( mpImpl
.is() ? mpImpl
->mxTable
.get() : nullptr );
1769 maLogicRect
= rObj
.maLogicRect
;
1770 maRect
= rObj
.maRect
;
1772 eTextKind
= rObj
.eTextKind
;
1773 bTextFrame
= rObj
.bTextFrame
;
1774 aTextSize
= rObj
.aTextSize
;
1775 bTextSizeDirty
= rObj
.bTextSizeDirty
;
1776 bNoShear
= rObj
.bNoShear
;
1777 bDisableAutoWidthOnDragging
= rObj
.bDisableAutoWidthOnDragging
;
1779 // use SdrTableObjImpl::operator= now to
1780 // copy model data and other stuff (see there)
1781 *mpImpl
= *rObj
.mpImpl
;
1787 const tools::Rectangle
& SdrTableObj::GetSnapRect() const
1793 void SdrTableObj::NbcSetSnapRect(const tools::Rectangle
& rRect
)
1795 NbcSetLogicRect( rRect
);
1799 const tools::Rectangle
& SdrTableObj::GetLogicRect() const
1805 void SdrTableObj::RecalcSnapRect()
1810 bool SdrTableObj::BegTextEdit(SdrOutliner
& rOutl
)
1812 if( pEdtOutl
!= nullptr )
1817 mbInEditMode
= true;
1819 rOutl
.Init( OutlinerMode::TextObject
);
1820 rOutl
.SetRefDevice(getSdrModelFromSdrObject().GetRefDevice());
1822 bool bUpdateMode
=rOutl
.GetUpdateMode();
1823 if (bUpdateMode
) rOutl
.SetUpdateMode(false);
1826 tools::Rectangle aEditArea
;
1827 TakeTextEditArea(&aPaperMin
,&aPaperMax
,&aEditArea
,nullptr);
1829 rOutl
.SetMinAutoPaperSize(aPaperMin
);
1830 rOutl
.SetMaxAutoPaperSize(aPaperMax
);
1831 rOutl
.SetPaperSize(aPaperMax
);
1833 if (bUpdateMode
) rOutl
.SetUpdateMode(true);
1835 EEControlBits nStat
=rOutl
.GetControlWord();
1836 nStat
|= EEControlBits::AUTOPAGESIZE
;
1837 nStat
&=~EEControlBits::STRETCHING
;
1838 rOutl
.SetControlWord(nStat
);
1840 OutlinerParaObject
* pPara
= GetOutlinerParaObject();
1842 rOutl
.SetText(*pPara
);
1844 rOutl
.UpdateFields();
1845 rOutl
.ClearModifyFlag();
1851 void SdrTableObj::EndTextEdit(SdrOutliner
& rOutl
)
1854 if (getSdrModelFromSdrObject().IsUndoEnabled() && !mpImpl
->maUndos
.empty())
1856 // These actions should be on the undo stack after text edit.
1857 for (std::unique_ptr
<SdrUndoAction
>& pAction
: mpImpl
->maUndos
)
1858 getSdrModelFromSdrObject().AddUndo( std::move(pAction
));
1859 mpImpl
->maUndos
.clear();
1861 getSdrModelFromSdrObject().AddUndo(getSdrModelFromSdrObject().GetSdrUndoFactory().CreateUndoGeoObject(*this));
1864 if(rOutl
.IsModified())
1866 std::unique_ptr
<OutlinerParaObject
> pNewText
;
1867 Paragraph
* p1stPara
= rOutl
.GetParagraph( 0 );
1868 sal_Int32 nParaCnt
= rOutl
.GetParagraphCount();
1872 // to remove the grey field background
1873 rOutl
.UpdateFields();
1875 // create new text object
1876 pNewText
= rOutl
.CreateParaObject( 0, nParaCnt
);
1878 SetOutlinerParaObject(std::move(pNewText
));
1883 EEControlBits nStat
= rOutl
.GetControlWord();
1884 nStat
&= ~EEControlBits::AUTOPAGESIZE
;
1885 rOutl
.SetControlWord(nStat
);
1887 mbInEditMode
= false;
1891 OutlinerParaObject
* SdrTableObj::GetOutlinerParaObject() const
1893 CellRef
xCell( getActiveCell() );
1895 return xCell
->GetOutlinerParaObject();
1901 void SdrTableObj::NbcSetOutlinerParaObject( std::unique_ptr
<OutlinerParaObject
> pTextObject
)
1903 CellRef
xCell( getActiveCell() );
1906 // Update HitTestOutliner
1907 const SdrTextObj
* pTestObj(getSdrModelFromSdrObject().GetHitTestOutliner().GetTextObj());
1909 if(pTestObj
&& pTestObj
->GetOutlinerParaObject() == xCell
->GetOutlinerParaObject())
1911 getSdrModelFromSdrObject().GetHitTestOutliner().SetTextObj(nullptr);
1914 xCell
->SetOutlinerParaObject( std::move(pTextObject
) );
1916 NbcAdjustTextFrameWidthAndHeight();
1921 void SdrTableObj::NbcSetLogicRect(const tools::Rectangle
& rRect
)
1924 ImpJustifyRect(maLogicRect
);
1925 const bool bWidth
= maLogicRect
.getWidth() != maRect
.getWidth();
1926 const bool bHeight
= maLogicRect
.getHeight() != maRect
.getHeight();
1927 maRect
= maLogicRect
;
1928 if (mpImpl
->mbSkipChangeLayout
)
1929 // Avoid distributing newly available space between existing cells.
1930 NbcAdjustTextFrameWidthAndHeight();
1932 NbcAdjustTextFrameWidthAndHeight(!bHeight
, !bWidth
);
1937 void SdrTableObj::AdjustToMaxRect( const tools::Rectangle
& rMaxRect
, bool /* bShrinkOnly = false */ )
1939 tools::Rectangle
aAdjustRect( rMaxRect
);
1940 aAdjustRect
.setHeight( GetLogicRect().getHeight() );
1941 SetLogicRect( aAdjustRect
);
1945 void SdrTableObj::NbcMove(const Size
& rSiz
)
1947 maLogicRect
.Move(rSiz
);
1948 SdrTextObj::NbcMove( rSiz
);
1950 mpImpl
->UpdateCells( maRect
);
1954 void SdrTableObj::NbcResize(const Point
& rRef
, const Fraction
& xFact
, const Fraction
& yFact
)
1956 tools::Rectangle
aOldRect( maLogicRect
);
1957 ResizeRect(maLogicRect
,rRef
,xFact
,yFact
);
1959 maRect
= maLogicRect
;
1960 NbcAdjustTextFrameWidthAndHeight( maLogicRect
.GetHeight() == aOldRect
.GetHeight(), maLogicRect
.GetWidth() == aOldRect
.GetWidth() );
1965 bool SdrTableObj::AdjustTextFrameWidthAndHeight()
1967 tools::Rectangle
aNewRect(maLogicRect
);
1968 bool bRet
=AdjustTextFrameWidthAndHeight(aNewRect
);
1971 tools::Rectangle aBoundRect0
;
1972 if (pUserCall
!=nullptr)
1973 aBoundRect0
=GetLastBoundRect();
1977 BroadcastObjectChange();
1978 SendUserCall(SdrUserCallType::Resize
,aBoundRect0
);
1984 bool SdrTableObj::AdjustTextFrameWidthAndHeight(tools::Rectangle
& rR
, bool bHeight
, bool bWidth
) const
1986 if(rR
.IsEmpty() || !mpImpl
.is() || !mpImpl
->mxTable
.is())
1989 tools::Rectangle
aRectangle( rR
);
1990 mpImpl
->LayoutTable( aRectangle
, !bWidth
, !bHeight
);
1992 if( aRectangle
!= rR
)
2004 void SdrTableObj::NbcReformatText()
2006 NbcAdjustTextFrameWidthAndHeight();
2010 bool SdrTableObj::IsVerticalWriting() const
2012 const SvxWritingModeItem
& rModeItem
= GetObjectItem( SDRATTR_TEXTDIRECTION
);
2013 return rModeItem
.GetValue() == css::text::WritingMode_TB_RL
;
2017 void SdrTableObj::SetVerticalWriting(bool bVertical
)
2019 if(bVertical
!= IsVerticalWriting() )
2021 SvxWritingModeItem
aModeItem( css::text::WritingMode_LR_TB
, SDRATTR_TEXTDIRECTION
);
2022 SetObjectItem( aModeItem
);
2027 WritingMode
SdrTableObj::GetWritingMode() const
2029 SfxStyleSheet
* pStyle
= GetStyleSheet();
2031 return WritingMode_LR_TB
;
2033 WritingMode eWritingMode
= WritingMode_LR_TB
;
2034 const SfxItemSet
&rSet
= pStyle
->GetItemSet();
2035 const SfxPoolItem
*pItem
;
2037 if ( rSet
.GetItemState( SDRATTR_TEXTDIRECTION
, false, &pItem
) == SfxItemState::SET
)
2038 eWritingMode
= static_cast< const SvxWritingModeItem
* >( pItem
)->GetValue();
2040 if ( ( eWritingMode
!= WritingMode_TB_RL
) &&
2041 ( rSet
.GetItemState( EE_PARA_WRITINGDIR
, false, &pItem
) == SfxItemState::SET
) )
2043 if ( static_cast< const SvxFrameDirectionItem
* >( pItem
)->GetValue() == SvxFrameDirection::Horizontal_LR_TB
)
2044 eWritingMode
= WritingMode_LR_TB
;
2046 eWritingMode
= WritingMode_RL_TB
;
2049 return eWritingMode
;
2052 void SdrTableObj::AddUndo(SdrUndoAction
* pUndo
)
2054 mpImpl
->maUndos
.push_back(std::unique_ptr
<SdrUndoAction
>(pUndo
));
2057 void SdrTableObj::SetSkipChangeLayout(bool bSkipChangeLayout
)
2059 mpImpl
->mbSkipChangeLayout
= bSkipChangeLayout
;
2062 bool SdrTableObj::IsReallyEdited() const
2064 return pEdtOutl
&& pEdtOutl
->IsModified();
2067 bool SdrTableObj::IsFontwork() const
2072 sal_uInt32
SdrTableObj::GetHdlCount() const
2074 sal_uInt32 nCount
= SdrTextObj::GetHdlCount();
2075 const sal_Int32 nRowCount
= mpImpl
->getRowCount();
2076 const sal_Int32 nColCount
= mpImpl
->getColumnCount();
2078 if( nRowCount
&& nColCount
)
2079 nCount
+= nRowCount
+ nColCount
+ 2 + 1;
2084 void SdrTableObj::AddToHdlList(SdrHdlList
& rHdlList
) const
2086 const sal_Int32 nRowCount
= mpImpl
->getRowCount();
2087 const sal_Int32 nColCount
= mpImpl
->getColumnCount();
2089 // first add row handles
2090 std::vector
<TableEdgeHdl
*> aRowEdges(nRowCount
+ 1);
2091 for (auto const & rEdge
: mpImpl
->mpLayouter
->getHorizontalEdges())
2093 Point
aPoint(maRect
.TopLeft());
2094 aPoint
.AdjustY(rEdge
.nPosition
);
2096 std::unique_ptr
<TableEdgeHdl
> pHdl(new TableEdgeHdl(aPoint
, true, rEdge
.nMin
, rEdge
.nMax
, nColCount
+ 1));
2097 pHdl
->SetPointNum(rEdge
.nIndex
);
2098 aRowEdges
[rEdge
.nIndex
] = pHdl
.get();
2099 rHdlList
.AddHdl(std::move(pHdl
));
2102 // second add column handles
2103 std::vector
<TableEdgeHdl
*> aColEdges(nColCount
+ 1);
2104 for (auto const & rEdge
: mpImpl
->mpLayouter
->getVerticalEdges())
2106 Point
aPoint(maRect
.TopLeft());
2107 aPoint
.AdjustX(rEdge
.nPosition
);
2109 std::unique_ptr
<TableEdgeHdl
> pHdl(new TableEdgeHdl(aPoint
, false, rEdge
.nMin
, rEdge
.nMax
, nRowCount
+ 1));
2110 pHdl
->SetPointNum(rEdge
.nIndex
);
2111 aColEdges
[rEdge
.nIndex
] = pHdl
.get();
2112 rHdlList
.AddHdl(std::move(pHdl
));
2115 // now add visible edges to row and column handles
2116 if( mpImpl
->mpLayouter
)
2118 TableLayouter
& rLayouter
= *mpImpl
->mpLayouter
;
2122 for( sal_Int32 nRow
= 0; nRow
<= nRowCount
; ++nRow
)
2124 const sal_Int32 nRowHeight
= (nRow
== nRowCount
) ? 0 : rLayouter
.getRowHeight(nRow
);
2127 for( sal_Int32 nCol
= 0; nCol
<= nColCount
; ++nCol
)
2129 const sal_Int32 nColWidth
= (nCol
== nColCount
) ? 0 : rLayouter
.getColumnWidth(nCol
);
2131 if( nRowHeight
> 0 )
2133 if( rLayouter
.isEdgeVisible( nCol
, nRow
, false ) )
2134 aColEdges
[nCol
]->SetEdge( nRow
, nY
, nY
+ nRowHeight
, (rLayouter
.getBorderLine( nCol
, nRow
, false ) == nullptr) ? Visible
: Invisible
);
2139 if( rLayouter
.isEdgeVisible( nCol
, nRow
, true ) )
2140 aRowEdges
[nRow
]->SetEdge( nCol
, nX
, nX
+ nColWidth
, (rLayouter
.getBorderLine( nCol
, nRow
, true ) == nullptr) ? Visible
: Invisible
);
2150 // add remaining handles
2151 SdrHdlList
tempList(nullptr);
2152 tempList
.AddHdl( std::make_unique
<TableBorderHdl
>( maRect
, !IsTextEditActive() ) );
2153 tempList
.AddHdl( std::make_unique
<SdrHdl
>(maRect
.TopLeft(),SdrHdlKind::UpperLeft
) );
2154 tempList
.AddHdl( std::make_unique
<SdrHdl
>(maRect
.TopCenter(),SdrHdlKind::Upper
) );
2155 tempList
.AddHdl( std::make_unique
<SdrHdl
>(maRect
.TopRight(),SdrHdlKind::UpperRight
) );
2156 tempList
.AddHdl( std::make_unique
<SdrHdl
>(maRect
.LeftCenter(),SdrHdlKind::Left
) );
2157 tempList
.AddHdl( std::make_unique
<SdrHdl
>(maRect
.RightCenter(),SdrHdlKind::Right
) );
2158 tempList
.AddHdl( std::make_unique
<SdrHdl
>(maRect
.BottomLeft(),SdrHdlKind::LowerLeft
) );
2159 tempList
.AddHdl( std::make_unique
<SdrHdl
>(maRect
.BottomCenter(),SdrHdlKind::Lower
) );
2160 tempList
.AddHdl( std::make_unique
<SdrHdl
>(maRect
.BottomRight(),SdrHdlKind::LowerRight
) );
2161 for( size_t nHdl
= 0; nHdl
< tempList
.GetHdlCount(); ++nHdl
)
2162 tempList
.GetHdl(nHdl
)->SetMoveOutside(true);
2163 tempList
.MoveTo(rHdlList
);
2165 const size_t nHdlCount
= rHdlList
.GetHdlCount();
2166 for( size_t nHdl
= 0; nHdl
< nHdlCount
; ++nHdl
)
2167 rHdlList
.GetHdl(nHdl
)->SetObj(const_cast<SdrTableObj
*>(this));
2172 bool SdrTableObj::hasSpecialDrag() const
2177 bool SdrTableObj::beginSpecialDrag(SdrDragStat
& rDrag
) const
2179 const SdrHdl
* pHdl
= rDrag
.GetHdl();
2180 const SdrHdlKind
eHdl((pHdl
== nullptr) ? SdrHdlKind::Move
: pHdl
->GetKind());
2184 case SdrHdlKind::UpperLeft
:
2185 case SdrHdlKind::Upper
:
2186 case SdrHdlKind::UpperRight
:
2187 case SdrHdlKind::Left
:
2188 case SdrHdlKind::Right
:
2189 case SdrHdlKind::LowerLeft
:
2190 case SdrHdlKind::Lower
:
2191 case SdrHdlKind::LowerRight
:
2192 case SdrHdlKind::Move
:
2197 case SdrHdlKind::User
:
2199 rDrag
.SetEndDragChangesAttributes(false);
2213 bool SdrTableObj::applySpecialDrag(SdrDragStat
& rDrag
)
2216 const SdrHdl
* pHdl
= rDrag
.GetHdl();
2217 const SdrHdlKind
eHdl((pHdl
== nullptr) ? SdrHdlKind::Move
: pHdl
->GetKind());
2221 case SdrHdlKind::UpperLeft
:
2222 case SdrHdlKind::Upper
:
2223 case SdrHdlKind::UpperRight
:
2224 case SdrHdlKind::Left
:
2225 case SdrHdlKind::Right
:
2226 case SdrHdlKind::LowerLeft
:
2227 case SdrHdlKind::Lower
:
2228 case SdrHdlKind::LowerRight
:
2230 const tools::Rectangle
aNewRectangle(ImpDragCalcRect(rDrag
));
2232 if (aNewRectangle
!= maRect
)
2234 NbcSetLogicRect(aNewRectangle
);
2240 case SdrHdlKind::Move
:
2242 NbcMove( Size( rDrag
.GetDX(), rDrag
.GetDY() ) );
2246 case SdrHdlKind::User
:
2248 rDrag
.SetEndDragChangesAttributes(false);
2250 const TableEdgeHdl
* pEdgeHdl
= dynamic_cast< const TableEdgeHdl
* >( pHdl
);
2256 rDrag
.SetEndDragChangesAttributes(true);
2257 rDrag
.SetEndDragChangesLayout(true);
2260 mpImpl
->DragEdge( pEdgeHdl
->IsHorizontalEdge(), pEdgeHdl
->GetPointNum(), pEdgeHdl
->GetValidDragOffset( rDrag
) );
2274 basegfx::B2DPolyPolygon
SdrTableObj::getSpecialDragPoly(const SdrDragStat
& rDrag
) const
2276 basegfx::B2DPolyPolygon aRetval
;
2277 const SdrHdl
* pHdl
= rDrag
.GetHdl();
2279 if( pHdl
&& (SdrHdlKind::User
== pHdl
->GetKind()) )
2281 const TableEdgeHdl
* pEdgeHdl
= dynamic_cast< const TableEdgeHdl
* >( pHdl
);
2285 aRetval
= pEdgeHdl
->getSpecialDragPoly( rDrag
);
2296 bool SdrTableObj::BegCreate(SdrDragStat
& rStat
)
2298 rStat
.SetOrtho4Possible();
2299 tools::Rectangle
aRect1(rStat
.GetStart(), rStat
.GetNow());
2301 rStat
.SetActionRect(aRect1
);
2307 bool SdrTableObj::MovCreate(SdrDragStat
& rStat
)
2309 tools::Rectangle aRect1
;
2310 rStat
.TakeCreateRect(aRect1
);
2311 ImpJustifyRect(aRect1
);
2312 rStat
.SetActionRect(aRect1
);
2313 maRect
= aRect1
; // for ObjName
2314 SetBoundRectDirty();
2315 bSnapRectDirty
=true;
2320 bool SdrTableObj::EndCreate(SdrDragStat
& rStat
, SdrCreateCmd eCmd
)
2322 rStat
.TakeCreateRect(maRect
);
2323 ImpJustifyRect(maRect
);
2324 return (eCmd
==SdrCreateCmd::ForceEnd
|| rStat
.GetPointCount()>=2);
2327 void SdrTableObj::BrkCreate(SdrDragStat
& /*rStat*/)
2332 bool SdrTableObj::BckCreate(SdrDragStat
& /*rStat*/)
2338 basegfx::B2DPolyPolygon
SdrTableObj::TakeCreatePoly(const SdrDragStat
& rDrag
) const
2340 tools::Rectangle aRect1
;
2341 rDrag
.TakeCreateRect(aRect1
);
2344 basegfx::B2DPolyPolygon aRetval
;
2345 const basegfx::B2DRange aRange
= vcl::unotools::b2DRectangleFromRectangle(aRect1
);
2346 aRetval
.append(basegfx::utils::createPolygonFromRect(aRange
));
2351 PointerStyle
SdrTableObj::GetCreatePointer() const
2353 return PointerStyle::Cross
;
2357 void SdrTableObj::createCell( CellRef
& xNewCell
)
2359 xNewCell
= Cell::create( *this );
2363 SdrObjGeoData
*SdrTableObj::NewGeoData() const
2365 return new TableObjectGeoData
;
2369 void SdrTableObj::SaveGeoData(SdrObjGeoData
& rGeo
) const
2371 DBG_ASSERT( dynamic_cast< TableObjectGeoData
* >( &rGeo
), "svx::SdrTableObj::SaveGeoData(), illegal geo data!" );
2372 SdrTextObj::SaveGeoData (rGeo
);
2374 static_cast<TableObjectGeoData
&>(rGeo
).maLogicRect
= maLogicRect
;
2378 void SdrTableObj::RestGeoData(const SdrObjGeoData
& rGeo
)
2380 DBG_ASSERT( dynamic_cast< const TableObjectGeoData
* >( &rGeo
), "svx::SdrTableObj::SaveGeoData(), illegal geo data!" );
2382 maLogicRect
= static_cast<const TableObjectGeoData
&>(rGeo
).maLogicRect
;
2384 SdrTextObj::RestGeoData (rGeo
);
2387 mpImpl
->LayoutTable(maRect
, false, false);
2391 void SdrTableObj::CropTableModelToSelection(const CellPos
& rStart
, const CellPos
& rEnd
)
2398 mpImpl
->CropTableModelToSelection(rStart
, rEnd
);
2401 void SdrTableObj::DistributeColumns( sal_Int32 nFirstColumn
, sal_Int32 nLastColumn
, const bool bOptimize
, const bool bMinimize
)
2403 if( mpImpl
.is() && mpImpl
->mpLayouter
)
2405 TableModelNotifyGuard
aGuard( mpImpl
->mxTable
.get() );
2406 mpImpl
->mpLayouter
->DistributeColumns( maRect
, nFirstColumn
, nLastColumn
, bOptimize
, bMinimize
);
2411 void SdrTableObj::DistributeRows( sal_Int32 nFirstRow
, sal_Int32 nLastRow
, const bool bOptimize
, const bool bMinimize
)
2413 if( mpImpl
.is() && mpImpl
->mpLayouter
)
2415 TableModelNotifyGuard
aGuard( mpImpl
->mxTable
.get() );
2416 mpImpl
->mpLayouter
->DistributeRows( maRect
, nFirstRow
, nLastRow
, bOptimize
, bMinimize
);
2421 void SdrTableObj::SetChanged()
2425 mpImpl
->LayoutTable( maRect
, false, false );
2428 ::SdrTextObj::SetChanged();
2432 void SdrTableObj::uno_lock()
2434 if( mpImpl
.is() && mpImpl
->mxTable
.is() )
2435 mpImpl
->mxTable
->lockBroadcasts();
2439 void SdrTableObj::uno_unlock()
2441 if( mpImpl
.is() && mpImpl
->mxTable
.is() )
2442 mpImpl
->mxTable
->unlockBroadcasts();
2445 void SdrTableObj::dumpAsXml(xmlTextWriterPtr pWriter
) const
2447 xmlTextWriterStartElement(pWriter
, BAD_CAST("SdrTableObj"));
2448 xmlTextWriterWriteFormatAttribute(pWriter
, BAD_CAST("ptr"), "%p", this);
2450 SdrObject::dumpAsXml(pWriter
);
2452 mpImpl
->dumpAsXml(pWriter
);
2454 xmlTextWriterEndElement(pWriter
);
2457 bool SdrTableObj::createTableEdgesJson(boost::property_tree::ptree
& rJsonRoot
)
2459 if (!mpImpl
.is() || !mpImpl
->mxTable
.is())
2462 tools::Rectangle aRect
= GetCurrentBoundRect();
2463 boost::property_tree::ptree aTableColumns
;
2465 aTableColumns
.put("tableOffset", convertMm100ToTwip(aRect
.Left()));
2467 boost::property_tree::ptree aEntries
;
2468 auto const & aEdges
= mpImpl
->mpLayouter
->getVerticalEdges();
2469 for (auto & rEdge
: aEdges
)
2471 if (rEdge
.nIndex
== 0)
2473 aTableColumns
.put("left", convertMm100ToTwip(rEdge
.nPosition
));
2475 else if (rEdge
.nIndex
== sal_Int32(aEdges
.size() - 1))
2477 aTableColumns
.put("right", convertMm100ToTwip(rEdge
.nPosition
));
2481 boost::property_tree::ptree aEntry
;
2482 aEntry
.put("position", convertMm100ToTwip(rEdge
.nPosition
));
2483 aEntry
.put("min", convertMm100ToTwip(rEdge
.nPosition
+ rEdge
.nMin
));
2484 aEntry
.put("max", convertMm100ToTwip(rEdge
.nPosition
+ rEdge
.nMax
));
2485 aEntry
.put("hidden", false);
2486 aEntries
.push_back(std::make_pair("", aEntry
));
2489 aTableColumns
.push_back(std::make_pair("entries", aEntries
));
2491 rJsonRoot
.add_child("columns", aTableColumns
);
2493 boost::property_tree::ptree aTableRows
;
2495 aTableRows
.put("tableOffset", convertMm100ToTwip(aRect
.Top()));
2497 boost::property_tree::ptree aEntries
;
2498 auto const & aEdges
= mpImpl
->mpLayouter
->getHorizontalEdges();
2499 for (auto & rEdge
: aEdges
)
2501 if (rEdge
.nIndex
== 0)
2503 aTableRows
.put("left", convertMm100ToTwip(rEdge
.nPosition
));
2505 else if (rEdge
.nIndex
== sal_Int32(aEdges
.size() - 1))
2507 aTableRows
.put("right", convertMm100ToTwip(rEdge
.nPosition
));
2511 boost::property_tree::ptree aEntry
;
2512 aEntry
.put("position", convertMm100ToTwip(rEdge
.nPosition
));
2513 aEntry
.put("min", convertMm100ToTwip(rEdge
.nPosition
+ rEdge
.nMin
));
2514 aEntry
.put("max", convertMm100ToTwip(rEdge
.nPosition
+ rEdge
.nMax
));
2515 aEntry
.put("hidden", false);
2516 aEntries
.push_back(std::make_pair("", aEntry
));
2519 aTableRows
.push_back(std::make_pair("entries", aEntries
));
2521 rJsonRoot
.add_child("rows", aTableRows
);
2527 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */